1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-22 11:13:46 +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

@@ -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],