1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 18:23:31 +00:00

Added helper method to abstract account initialization in tests.

This commit is contained in:
Todd Martin
2025-12-09 18:17:13 -05:00
parent 57631fb0ce
commit 9bcae12b95
14 changed files with 94 additions and 129 deletions

View File

@@ -15,6 +15,7 @@ import {
} from "@bitwarden/common/platform/abstractions/environment.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { mockAccountInfoWith } from "@bitwarden/common/spec";
import { UserId } from "@bitwarden/common/types/guid";
import { AccountSwitcherService } from "./account-switcher.service";
@@ -71,12 +72,10 @@ describe("AccountSwitcherService", () => {
describe("availableAccounts$", () => {
it("should return all logged in accounts and an add account option when accounts are less than 5", async () => {
const accountInfo: AccountInfo = {
const accountInfo = mockAccountInfoWith({
name: "Test User 1",
email: "test1@email.com",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
};
});
avatarService.getUserAvatarColor$.mockReturnValue(of("#cccccc"));
accountsSubject.next({ ["1" as UserId]: accountInfo, ["2" as UserId]: accountInfo });
@@ -110,12 +109,10 @@ describe("AccountSwitcherService", () => {
const seedAccounts: Record<UserId, AccountInfo> = {};
const seedStatuses: Record<UserId, AuthenticationStatus> = {};
for (let i = 0; i < numberOfAccounts; i++) {
seedAccounts[`${i}` as UserId] = {
seedAccounts[`${i}` as UserId] = mockAccountInfoWith({
email: `test${i}@email.com`,
emailVerified: true,
name: "Test User ${i}",
creationDate: "2024-01-01T00:00:00.000Z",
};
});
seedStatuses[`${i}` as UserId] = AuthenticationStatus.Unlocked;
}
avatarService.getUserAvatarColor$.mockReturnValue(of("#cccccc"));
@@ -135,12 +132,10 @@ describe("AccountSwitcherService", () => {
);
it("excludes logged out accounts", async () => {
const user1AccountInfo: AccountInfo = {
const user1AccountInfo = mockAccountInfoWith({
name: "Test User 1",
email: "",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
};
});
accountsSubject.next({ ["1" as UserId]: user1AccountInfo });
authStatusSubject.next({ ["1" as UserId]: AuthenticationStatus.LoggedOut });
accountsSubject.next({

View File

@@ -4,7 +4,7 @@ import { BehaviorSubject, firstValueFrom, of } from "rxjs";
import { CollectionService } from "@bitwarden/admin-console/common";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
import { ExtensionCommand } from "@bitwarden/common/autofill/constants";
@@ -17,6 +17,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
import { ThemeTypes } from "@bitwarden/common/platform/enums";
import { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service";
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
import { mockAccountInfoWith } from "@bitwarden/common/spec";
import { UserId } from "@bitwarden/common/types/guid";
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@@ -80,12 +81,12 @@ describe("NotificationBackground", () => {
const organizationService = mock<OrganizationService>();
const userId = "testId" as UserId;
const activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>({
const activeAccountSubject = new BehaviorSubject({
id: userId,
email: "test@example.com",
emailVerified: true,
name: "Test User",
creationDate: "2024-01-01T00:00:00.000Z",
...mockAccountInfoWith({
email: "test@example.com",
name: "Test User",
}),
});
beforeEach(() => {

View File

@@ -2,7 +2,7 @@ import { NgZone } from "@angular/core";
import { mock, MockProxy } from "jest-mock-extended";
import { BehaviorSubject, filter, firstValueFrom, of, take, timeout, timer } from "rxjs";
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
@@ -10,7 +10,7 @@ import { EncryptService } from "@bitwarden/common/key-management/crypto/abstract
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { FakeAccountService } from "@bitwarden/common/spec";
import { mockAccountInfoWith , FakeAccountService } from "@bitwarden/common/spec";
import { CsprngArray } from "@bitwarden/common/types/csprng";
import { UserId } from "@bitwarden/common/types/guid";
import { DialogService } from "@bitwarden/components";
@@ -23,19 +23,15 @@ import { BiometricMessageHandlerService } from "./biometric-message-handler.serv
const SomeUser = "SomeUser" as UserId;
const AnotherUser = "SomeOtherUser" as UserId;
const accounts: Record<UserId, AccountInfo> = {
[SomeUser]: {
const accounts = {
[SomeUser]: mockAccountInfoWith({
name: "some user",
email: "some.user@example.com",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
},
[AnotherUser]: {
}),
[AnotherUser]: mockAccountInfoWith({
name: "some other user",
email: "some.other.user@example.com",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
},
}),
};
describe("BiometricMessageHandlerService", () => {

View File

@@ -2,14 +2,18 @@ import { TestBed } from "@angular/core/testing";
import { BehaviorSubject, firstValueFrom, take, timeout } from "rxjs";
import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common";
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { DeviceType } from "@bitwarden/common/enums";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { StateProvider } from "@bitwarden/common/platform/state";
import { FakeStateProvider, mockAccountServiceWith } from "@bitwarden/common/spec";
import {
FakeStateProvider,
mockAccountServiceWith,
mockAccountInfoWith,
} from "@bitwarden/common/spec";
import { UserId } from "@bitwarden/common/types/guid";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
@@ -27,13 +31,11 @@ describe("VaultBannersService", () => {
const fakeStateProvider = new FakeStateProvider(mockAccountServiceWith(userId));
const getEmailVerified = jest.fn().mockResolvedValue(true);
const lastSync$ = new BehaviorSubject<Date | null>(null);
const accounts$ = new BehaviorSubject<Record<UserId, AccountInfo>>({
[userId]: {
const accounts$ = new BehaviorSubject({
[userId]: mockAccountInfoWith({
email: "test@bitwarden.com",
emailVerified: true,
name: "name",
creationDate: "2024-01-01T00:00:00.000Z",
} as AccountInfo,
}),
});
const pendingAuthRequests$ = new BehaviorSubject<Array<AuthRequestResponse>>([]);

View File

@@ -2,14 +2,13 @@ import { Router } from "@angular/router";
import { mock } from "jest-mock-extended";
import { of } from "rxjs";
import { AccountInfo } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SingleUserState, StateProvider } from "@bitwarden/common/platform/state";
import { SyncService } from "@bitwarden/common/platform/sync";
import { FakeAccountService } from "@bitwarden/common/spec";
import { mockAccountInfoWith , FakeAccountService } from "@bitwarden/common/spec";
import { UserId } from "@bitwarden/common/types/guid";
import { DialogService, ToastService } from "@bitwarden/components";
import { LogService } from "@bitwarden/logging";
@@ -22,19 +21,15 @@ import { PromptMigrationPasswordComponent } from "./prompt-migration-password.co
const SomeUser = "SomeUser" as UserId;
const AnotherUser = "SomeOtherUser" as UserId;
const accounts: Record<UserId, AccountInfo> = {
[SomeUser]: {
const accounts = {
[SomeUser]: mockAccountInfoWith({
name: "some user",
email: "some.user@example.com",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
},
[AnotherUser]: {
}),
[AnotherUser]: mockAccountInfoWith({
name: "some other user",
email: "some.other.user@example.com",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
},
}),
};
describe("DefaultEncryptedMigrationsSchedulerService", () => {

View File

@@ -6,20 +6,26 @@ import { ReplaySubject, combineLatest, map, Observable } from "rxjs";
import { Account, AccountInfo, AccountService } from "../src/auth/abstractions/account.service";
import { UserId } from "../src/types/guid";
/**
* Creates a mock AccountInfo object with sensible defaults that can be overridden.
* Use this when you need just an AccountInfo object in tests.
*/
export function mockAccountInfoWith(info: Partial<AccountInfo> = {}): AccountInfo {
return {
name: "name",
email: "email",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
...info,
};
}
export function mockAccountServiceWith(
userId: UserId,
info: Partial<AccountInfo> = {},
activity: Record<UserId, Date> = {},
): FakeAccountService {
const fullInfo: AccountInfo = {
...info,
...{
name: "name",
email: "email",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
},
};
const fullInfo = mockAccountInfoWith(info);
const fullActivity = { [userId]: new Date(), ...activity };

View File

@@ -6,6 +6,7 @@
import { MockProxy, mock } from "jest-mock-extended";
import { firstValueFrom } from "rxjs";
import { mockAccountInfoWith } from "../../../spec/fake-account-service";
import { FakeGlobalState } from "../../../spec/fake-state";
import {
FakeGlobalStateProvider,
@@ -27,12 +28,7 @@ import {
} from "./account.service";
describe("accountInfoEqual", () => {
const accountInfo: AccountInfo = {
name: "name",
email: "email",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
};
const accountInfo = mockAccountInfoWith();
it("compares nulls", () => {
expect(accountInfoEqual(null, null)).toBe(true);
@@ -79,12 +75,7 @@ describe("accountInfoEqual", () => {
});
it("compares undefined creationDate", () => {
const accountWithoutCreationDate: AccountInfo = {
name: "name",
email: "email",
emailVerified: true,
creationDate: undefined,
};
const accountWithoutCreationDate = mockAccountInfoWith({ creationDate: undefined });
const same = { ...accountWithoutCreationDate };
const different = { ...accountWithoutCreationDate, creationDate: "2024-01-01T00:00:00.000Z" };
@@ -103,12 +94,10 @@ describe("accountService", () => {
let activeAccountIdState: FakeGlobalState<UserId>;
let accountActivityState: FakeGlobalState<Record<UserId, Date>>;
const userId = Utils.newGuid() as UserId;
const userInfo = {
const userInfo = mockAccountInfoWith({
email: "email",
name: "name",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
};
});
beforeEach(() => {
messagingService = mock();
@@ -309,10 +298,10 @@ describe("accountService", () => {
});
it("should update from undefined to a defined creation date", async () => {
const accountWithoutCreationDate: AccountInfo = {
const accountWithoutCreationDate = mockAccountInfoWith({
...userInfo,
creationDate: undefined,
};
});
accountsState.stateSubject.next({ [userId]: accountWithoutCreationDate });
const newCreationDate = "2024-06-15T12:30:00.000Z";

View File

@@ -15,6 +15,7 @@ import {
SystemNotificationEvent,
SystemNotificationsService,
} from "@bitwarden/common/platform/system-notifications/system-notifications.service";
import { mockAccountInfoWith } from "@bitwarden/common/spec/fake-account-service";
import { UserId } from "@bitwarden/user-core";
import { AuthRequestAnsweringService } from "./auth-request-answering.service";
@@ -48,20 +49,16 @@ describe("AuthRequestAnsweringService", () => {
// Common defaults
authService.activeAccountStatus$ = of(AuthenticationStatus.Locked);
const accountInfo = mockAccountInfoWith({
email: "user@example.com",
name: "User",
});
accountService.activeAccount$ = of({
id: userId,
email: "user@example.com",
emailVerified: true,
name: "User",
creationDate: "2024-01-01T00:00:00.000Z",
...accountInfo,
});
accountService.accounts$ = of({
[userId]: {
email: "user@example.com",
emailVerified: true,
name: "User",
creationDate: "2024-01-01T00:00:00.000Z",
},
[userId]: accountInfo,
});
(masterPasswordService.forceSetPasswordReason$ as jest.Mock).mockReturnValue(
of(ForceSetPasswordReason.None),

View File

@@ -8,12 +8,13 @@ import { OrganizationUserApiService } from "@bitwarden/admin-console/common";
// eslint-disable-next-line no-restricted-imports
import { KeyService } from "@bitwarden/key-management";
import { mockAccountInfoWith } from "../../../spec/fake-account-service";
import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction";
import { OrganizationAutoEnrollStatusResponse } from "../../admin-console/models/response/organization-auto-enroll-status.response";
import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service";
import { I18nService } from "../../platform/abstractions/i18n.service";
import { UserId } from "../../types/guid";
import { Account, AccountInfo, AccountService } from "../abstractions/account.service";
import { Account, AccountService } from "../abstractions/account.service";
import { PasswordResetEnrollmentServiceImplementation } from "./password-reset-enrollment.service.implementation";
@@ -96,12 +97,10 @@ describe("PasswordResetEnrollmentServiceImplementation", () => {
const encryptedKey = { encryptedString: "encryptedString" };
organizationApiService.getKeys.mockResolvedValue(orgKeyResponse as any);
const user1AccountInfo: AccountInfo = {
const user1AccountInfo = mockAccountInfoWith({
name: "Test User 1",
email: "test1@email.com",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
};
});
activeAccountSubject.next(Object.assign(user1AccountInfo, { id: "userId" as UserId }));
keyService.userKey$.mockReturnValue(of({ key: "key" } as any));

View File

@@ -7,6 +7,7 @@ import { InternalPolicyService } from "@bitwarden/common/admin-console/abstracti
import { AuthRequestAnsweringServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { mockAccountInfoWith } from "../../../../spec";
import { AccountService } from "../../../auth/abstractions/account.service";
import { AuthService } from "../../../auth/abstractions/auth.service";
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
@@ -174,12 +175,10 @@ describe("DefaultServerNotificationsService (multi-user)", () => {
const currentAccounts = (userAccounts$.getValue() as Record<string, any>) ?? {};
userAccounts$.next({
...currentAccounts,
[userId]: {
[userId]: mockAccountInfoWith({
email: "email",
name: "Test Name",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
},
}),
} as any);
}

View File

@@ -8,7 +8,7 @@ import { InternalPolicyService } from "@bitwarden/common/admin-console/abstracti
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { AuthRequestAnsweringServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction";
import { awaitAsync } from "../../../../spec";
import { awaitAsync, mockAccountInfoWith } from "../../../../spec";
import { Matrix } from "../../../../spec/matrix";
import { AccountService } from "../../../auth/abstractions/account.service";
import { AuthService } from "../../../auth/abstractions/auth.service";
@@ -139,22 +139,18 @@ describe("NotificationsService", () => {
activeAccount.next(null);
accounts.next({} as any);
} else {
activeAccount.next({
id: userId,
const accountInfo = mockAccountInfoWith({
email: "email",
name: "Test Name",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
});
activeAccount.next({
id: userId,
...accountInfo,
});
const current = (accounts.getValue() as Record<string, any>) ?? {};
accounts.next({
...current,
[userId]: {
email: "email",
name: "Test Name",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
},
[userId]: accountInfo,
} as any);
}
}
@@ -362,10 +358,10 @@ describe("NotificationsService", () => {
appIdService.getAppId.mockResolvedValue("test-app-id");
activeAccount.next({
id: mockUser1,
email: "email",
name: "Test Name",
emailVerified: true,
creationDate: "2024-01-01T00:00:00.000Z",
...mockAccountInfoWith({
email: "email",
name: "Test Name",
}),
});
});

View File

@@ -12,9 +12,9 @@ import {
FakeAccountService,
FakeStateProvider,
mockAccountServiceWith,
mockAccountInfoWith,
} from "../../../../spec";
import { ApiService } from "../../../abstractions/api.service";
import { AccountInfo } from "../../../auth/abstractions/account.service";
import { EncryptedString } from "../../../key-management/crypto/models/enc-string";
import { UserId } from "../../../types/guid";
import { UserKey } from "../../../types/key";
@@ -92,12 +92,10 @@ describe("DefaultSdkService", () => {
.calledWith(userId)
.mockReturnValue(new BehaviorSubject(mock<Environment>()));
accountService.accounts$ = of({
[userId]: {
[userId]: mockAccountInfoWith({
email: "email",
emailVerified: true,
name: "name",
creationDate: "2024-01-01T00:00:00.000Z",
} as AccountInfo,
}),
});
kdfConfigService.getKdfConfig$
.calledWith(userId)

View File

@@ -8,9 +8,9 @@ import {
FakeAccountService,
FakeStateProvider,
mockAccountServiceWith,
mockAccountInfoWith,
} from "../../../../spec";
import { ApiService } from "../../../abstractions/api.service";
import { AccountInfo } from "../../../auth/abstractions/account.service";
import { UserId } from "../../../types/guid";
import { ConfigService } from "../../abstractions/config/config.service";
import { Environment, EnvironmentService } from "../../abstractions/environment.service";
@@ -76,12 +76,10 @@ describe("DefaultRegisterSdkService", () => {
.calledWith(userId)
.mockReturnValue(new BehaviorSubject(mock<Environment>()));
accountService.accounts$ = of({
[userId]: {
[userId]: mockAccountInfoWith({
email: "email",
emailVerified: true,
name: "name",
creationDate: "2024-01-01T00:00:00.000Z",
} as AccountInfo,
}),
});
});
@@ -130,12 +128,10 @@ describe("DefaultRegisterSdkService", () => {
it("destroys the internal SDK client when the account is removed (logout)", async () => {
const accounts$ = new BehaviorSubject({
[userId]: {
[userId]: mockAccountInfoWith({
email: "email",
emailVerified: true,
name: "name",
creationDate: "2024-01-01T00:00:00.000Z",
} as AccountInfo,
}),
});
accountService.accounts$ = accounts$;

View File

@@ -2,9 +2,10 @@ import { ComponentFixture, TestBed } from "@angular/core/testing";
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
import { BehaviorSubject } from "rxjs";
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { mockAccountInfoWith } from "@bitwarden/common/spec";
import { UserId } from "@bitwarden/common/types/guid";
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
@@ -47,12 +48,7 @@ describe("AddEditFolderDialogComponent", () => {
showToast.mockClear();
const userId = "" as UserId;
const accountInfo: AccountInfo = {
email: "",
emailVerified: true,
name: undefined,
creationDate: undefined,
};
const accountInfo = mockAccountInfoWith();
await TestBed.configureTestingModule({
imports: [AddEditFolderDialogComponent, NoopAnimationsModule],