From 57ad18fb4d51b5cf3ab73db1bc94f7ccd2f5b36e Mon Sep 17 00:00:00 2001 From: Brandon Date: Wed, 15 Jan 2025 13:37:59 -0500 Subject: [PATCH] wire vNextOrganizationService in tests --- bitwarden_license/bit-common/jest.config.js | 14 ++++- bitwarden_license/bit-web/jest.config.js | 14 ++++- .../guards/project-access.guard.spec.ts | 21 +++++-- .../service-account-access.guard.spec.ts | 21 +++++-- .../access-policy-selector.service.spec.ts | 56 +++++++++++-------- ...sword-health-members-uri.component.spec.ts | 10 +++- .../models/data/organization.data.spec.ts | 2 +- 7 files changed, 93 insertions(+), 45 deletions(-) diff --git a/bitwarden_license/bit-common/jest.config.js b/bitwarden_license/bit-common/jest.config.js index a0441b01883..ab31a4c26ca 100644 --- a/bitwarden_license/bit-common/jest.config.js +++ b/bitwarden_license/bit-common/jest.config.js @@ -7,9 +7,17 @@ module.exports = { ...sharedConfig, displayName: "bit-common tests", testEnvironment: "jsdom", - moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), + moduleNameMapper: pathsToModuleNameMapper( + { + "@bitwarden/common/spec": ["../../libs/common/spec"], + "@bitwarden/common": ["../../libs/common/src/*"], + "@bitwarden/admin-console/common": ["/libs/admin-console/src/common"], + ...(compilerOptions?.paths ?? {}), + }, + { + prefix: "/", + }, + ), setupFilesAfterEnv: ["/test.setup.ts"], transformIgnorePatterns: ["node_modules/(?!(.*\\.mjs$|@angular|rxjs|@bitwarden))"], moduleFileExtensions: ["ts", "js", "html", "mjs"], diff --git a/bitwarden_license/bit-web/jest.config.js b/bitwarden_license/bit-web/jest.config.js index 17b7139049a..9c9c61b2402 100644 --- a/bitwarden_license/bit-web/jest.config.js +++ b/bitwarden_license/bit-web/jest.config.js @@ -9,7 +9,15 @@ module.exports = { ...sharedConfig, preset: "jest-preset-angular", setupFilesAfterEnv: ["../../apps/web/test.setup.ts"], - moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), + moduleNameMapper: pathsToModuleNameMapper( + { + "@bitwarden/common/spec": ["../../libs/common/spec"], + "@bitwarden/common": ["../../libs/common/src/*"], + "@bitwarden/admin-console/common": ["/libs/admin-console/src/common"], + ...(compilerOptions?.paths ?? {}), + }, + { + prefix: "/", + }, + ), }; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts index 631f6409748..a9cc10e24d4 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts @@ -3,10 +3,15 @@ import { TestBed } from "@angular/core/testing"; import { Router } from "@angular/router"; import { RouterTestingModule } from "@angular/router/testing"; import { MockProxy, mock } from "jest-mock-extended"; +import { of } from "rxjs"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { vNextOrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/vnext.organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { ToastService } from "@bitwarden/components"; import { RouterService } from "../../../../../../../apps/web/src/app/core/router.service"; @@ -26,12 +31,14 @@ export class GuardedRouteTestComponent {} export class RedirectTestComponent {} describe("Project Redirect Guard", () => { - let organizationService: MockProxy; + let organizationService: MockProxy; let routerService: MockProxy; let projectServiceMock: MockProxy; let i18nServiceMock: MockProxy; let toastService: MockProxy; let router: Router; + let accountService: FakeAccountService; + const userId = Utils.newGuid() as UserId; const smOrg1 = { id: "123", canAccessSecretsManager: true } as Organization; const projectView = { @@ -45,11 +52,12 @@ describe("Project Redirect Guard", () => { } as ProjectView; beforeEach(async () => { - organizationService = mock(); + organizationService = mock(); routerService = mock(); projectServiceMock = mock(); i18nServiceMock = mock(); toastService = mock(); + accountService = mockAccountServiceWith(userId); TestBed.configureTestingModule({ imports: [ @@ -70,7 +78,8 @@ describe("Project Redirect Guard", () => { ]), ], providers: [ - { provide: OrganizationService, useValue: organizationService }, + { provide: vNextOrganizationService, useValue: organizationService }, + { provide: AccountService, useValue: accountService }, { provide: RouterService, useValue: routerService }, { provide: ProjectService, useValue: projectServiceMock }, { provide: I18nService, useValue: i18nServiceMock }, @@ -83,7 +92,7 @@ describe("Project Redirect Guard", () => { it("redirects to sm/{orgId}/projects/{projectId} if project exists", async () => { // Arrange - organizationService.getAll.mockResolvedValue([smOrg1]); + organizationService.organizations$.mockReturnValue(of([smOrg1])); projectServiceMock.getByProjectId.mockReturnValue(Promise.resolve(projectView)); // Act @@ -95,7 +104,7 @@ describe("Project Redirect Guard", () => { it("redirects to sm/projects if project does not exist", async () => { // Arrange - organizationService.getAll.mockResolvedValue([smOrg1]); + organizationService.organizations$.mockReturnValue(of([smOrg1])); // Act await router.navigateByUrl("sm/123/projects/124"); diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts index ebd00a83ea5..592ffbb80cb 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts @@ -3,10 +3,15 @@ import { TestBed } from "@angular/core/testing"; import { Router } from "@angular/router"; import { RouterTestingModule } from "@angular/router/testing"; import { MockProxy, mock } from "jest-mock-extended"; +import { of } from "rxjs"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { vNextOrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/vnext.organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { ToastService } from "@bitwarden/components"; import { RouterService } from "../../../../../../../../clients/apps/web/src/app/core/router.service"; @@ -26,12 +31,14 @@ export class GuardedRouteTestComponent {} export class RedirectTestComponent {} describe("Service account Redirect Guard", () => { - let organizationService: MockProxy; + let organizationService: MockProxy; let routerService: MockProxy; let serviceAccountServiceMock: MockProxy; let i18nServiceMock: MockProxy; let toastService: MockProxy; let router: Router; + let accountService: FakeAccountService; + const userId = Utils.newGuid() as UserId; const smOrg1 = { id: "123", canAccessSecretsManager: true } as Organization; const serviceAccountView = { @@ -41,11 +48,12 @@ describe("Service account Redirect Guard", () => { } as ServiceAccountView; beforeEach(async () => { - organizationService = mock(); + organizationService = mock(); routerService = mock(); serviceAccountServiceMock = mock(); i18nServiceMock = mock(); toastService = mock(); + accountService = mockAccountServiceWith(userId); TestBed.configureTestingModule({ imports: [ @@ -66,7 +74,8 @@ describe("Service account Redirect Guard", () => { ]), ], providers: [ - { provide: OrganizationService, useValue: organizationService }, + { provide: vNextOrganizationService, useValue: organizationService }, + { provide: AccountService, useValue: accountService }, { provide: RouterService, useValue: routerService }, { provide: ServiceAccountService, useValue: serviceAccountServiceMock }, { provide: I18nService, useValue: i18nServiceMock }, @@ -79,7 +88,7 @@ describe("Service account Redirect Guard", () => { it("redirects to sm/{orgId}/machine-accounts/{serviceAccountId} if machine account exists", async () => { // Arrange - organizationService.getAll.mockResolvedValue([smOrg1]); + organizationService.organizations$.mockReturnValue(of([smOrg1])); serviceAccountServiceMock.getByServiceAccountId.mockReturnValue( Promise.resolve(serviceAccountView), ); @@ -93,7 +102,7 @@ describe("Service account Redirect Guard", () => { it("redirects to sm/machine-accounts if machine account does not exist", async () => { // Arrange - organizationService.getAll.mockResolvedValue([smOrg1]); + organizationService.organizations$.mockReturnValue(of([smOrg1])); // Act await router.navigateByUrl("sm/123/machine-accounts/124"); diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.service.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.service.spec.ts index 05b677d490a..b54f8062145 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.service.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.service.spec.ts @@ -1,8 +1,13 @@ import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { vNextOrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/vnext.organization.service.abstraction"; import { OrganizationUserType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { AccessPolicySelectorService } from "./access-policy-selector.service"; import { ApItemValueType } from "./models/ap-item-value.type"; @@ -11,14 +16,17 @@ import { ApItemEnum } from "./models/enums/ap-item.enum"; import { ApPermissionEnum } from "./models/enums/ap-permission.enum"; describe("AccessPolicySelectorService", () => { - let organizationService: MockProxy; + let organizationService: MockProxy; + let accountService: FakeAccountService; + const userId = Utils.newGuid() as UserId; let sut: AccessPolicySelectorService; beforeEach(() => { - organizationService = mock(); + organizationService = mock(); + accountService = mockAccountServiceWith(userId); - sut = new AccessPolicySelectorService(organizationService); + sut = new AccessPolicySelectorService(organizationService, accountService as AccountService); }); afterEach(() => jest.resetAllMocks()); @@ -26,7 +34,7 @@ describe("AccessPolicySelectorService", () => { describe("showAccessRemovalWarning", () => { it("returns false when current user is admin", async () => { const org = orgFactory(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = []; @@ -38,7 +46,7 @@ describe("AccessPolicySelectorService", () => { it("returns false when current user is owner", async () => { const org = orgFactory(); org.type = OrganizationUserType.Owner; - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = []; @@ -49,7 +57,7 @@ describe("AccessPolicySelectorService", () => { it("returns true when current user isn't owner/admin and all policies are removed", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = []; @@ -60,7 +68,7 @@ describe("AccessPolicySelectorService", () => { it("returns true when current user isn't owner/admin and user policy is set to canRead", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = []; selectedPolicyValues.push( @@ -79,7 +87,7 @@ describe("AccessPolicySelectorService", () => { it("returns false when current user isn't owner/admin and user policy is set to canReadWrite", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = [ createApItemValueType( @@ -97,7 +105,7 @@ describe("AccessPolicySelectorService", () => { it("returns true when current user isn't owner/admin and a group Read policy is submitted that the user is a member of", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = [ createApItemValueType( @@ -118,7 +126,7 @@ describe("AccessPolicySelectorService", () => { it("returns false when current user isn't owner/admin and a group ReadWrite policy is submitted that the user is a member of", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = [ createApItemValueType( @@ -139,7 +147,7 @@ describe("AccessPolicySelectorService", () => { it("returns true when current user isn't owner/admin and a group ReadWrite policy is submitted that the user is not a member of", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = [ createApItemValueType( @@ -160,7 +168,7 @@ describe("AccessPolicySelectorService", () => { it("returns false when current user isn't owner/admin, user policy is set to CanRead, and user is in read write group", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = [ createApItemValueType( @@ -187,7 +195,7 @@ describe("AccessPolicySelectorService", () => { it("returns true when current user isn't owner/admin, user policy is set to CanRead, and user is not in ReadWrite group", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = [ createApItemValueType( @@ -214,7 +222,7 @@ describe("AccessPolicySelectorService", () => { it("returns true when current user isn't owner/admin, user policy is set to CanRead, and user is in Read group", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const selectedPolicyValues: ApItemValueType[] = [ createApItemValueType( @@ -242,7 +250,7 @@ describe("AccessPolicySelectorService", () => { describe("showSecretAccessRemovalWarning", () => { it("returns false when there are no current access policies", async () => { const org = orgFactory(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = []; const selectedPolicyValues: ApItemValueType[] = []; @@ -257,7 +265,7 @@ describe("AccessPolicySelectorService", () => { }); it("returns false when current user is admin", async () => { const org = orgFactory(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( @@ -281,7 +289,7 @@ describe("AccessPolicySelectorService", () => { it("returns false when current user is owner", async () => { const org = orgFactory(); org.type = OrganizationUserType.Owner; - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( @@ -304,7 +312,7 @@ describe("AccessPolicySelectorService", () => { }); it("returns false when current non-admin user doesn't have Read, Write access with current access policies -- user policy", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( @@ -327,7 +335,7 @@ describe("AccessPolicySelectorService", () => { }); it("returns false when current non-admin user doesn't have Read, Write access with current access policies -- group policy", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( @@ -352,7 +360,7 @@ describe("AccessPolicySelectorService", () => { }); it("returns true when current non-admin user has Read, Write access with current access policies and doesn't with selected -- user policy", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( @@ -381,7 +389,7 @@ describe("AccessPolicySelectorService", () => { }); it("returns true when current non-admin user has Read, Write access with current access policies and doesn't with selected -- group policy", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( @@ -415,7 +423,7 @@ describe("AccessPolicySelectorService", () => { }); it("returns false when current non-admin user has Read, Write access with current access policies and does with selected -- user policy", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( @@ -446,7 +454,7 @@ describe("AccessPolicySelectorService", () => { }); it("returns false when current non-admin user has Read, Write access with current access policies and does with selected -- group policy", async () => { const org = setupUserOrg(); - organizationService.get.calledWith(org.id).mockResolvedValue(org); + organizationService.organizations$.calledWith(userId).mockReturnValue(of([org])); const currentAccessPolicies: ApItemViewType[] = [ createApItemViewType( diff --git a/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts index 1e9e4171bc3..eccf4abbb18 100644 --- a/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts @@ -9,9 +9,13 @@ import { } from "@bitwarden/bit-common/tools/reports/risk-insights"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { vNextOrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/vnext.organization.service.abstraction"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { mockAccountServiceWith } from "@bitwarden/common/spec"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { TableModule } from "@bitwarden/components"; import { LooseComponentsModule } from "@bitwarden/web-vault/app/shared"; @@ -24,6 +28,7 @@ describe("PasswordHealthMembersUriComponent", () => { let fixture: ComponentFixture; let cipherServiceMock: MockProxy; const passwordHealthServiceMock = mock(); + const userId = Utils.newGuid() as UserId; const activeRouteParams = convertToParamMap({ organizationId: "orgId" }); @@ -35,7 +40,8 @@ describe("PasswordHealthMembersUriComponent", () => { { provide: CipherService, useValue: cipherServiceMock }, { provide: I18nService, useValue: mock() }, { provide: AuditService, useValue: mock() }, - { provide: OrganizationService, useValue: mock() }, + { provide: vNextOrganizationService, useValue: mock() }, + { provide: AccountService, useValue: mockAccountServiceWith(userId) }, { provide: PasswordStrengthServiceAbstraction, useValue: mock(), diff --git a/libs/common/src/admin-console/models/data/organization.data.spec.ts b/libs/common/src/admin-console/models/data/organization.data.spec.ts index da9a82e7c5c..8cdc97fb3f6 100644 --- a/libs/common/src/admin-console/models/data/organization.data.spec.ts +++ b/libs/common/src/admin-console/models/data/organization.data.spec.ts @@ -1,6 +1,6 @@ import { ProductTierType } from "../../../billing/enums/product-tier-type.enum"; import { OrganizationUserStatusType, OrganizationUserType } from "../../enums"; -import { ORGANIZATIONS } from "../../services/organization/organization.service"; +import { ORGANIZATIONS } from "../../services/organization/vnext-organization.state"; import { OrganizationData } from "./organization.data";