diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts index 4187900060b..a1ac434d590 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts @@ -11,6 +11,7 @@ import { ProviderService } from "@bitwarden/common/admin-console/abstractions/pr import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/platform/sync"; import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; @@ -24,6 +25,7 @@ describe("ProductSwitcherService", () => { let organizationService: MockProxy; let providerService: MockProxy; let accountService: FakeAccountService; + let platformUtilsService: MockProxy; let activeRouteParams = convertToParamMap({ organizationId: "1234" }); const getLastSync = jest.fn().mockResolvedValue(new Date("2024-05-14")); const userId = Utils.newGuid() as UserId; @@ -43,11 +45,13 @@ describe("ProductSwitcherService", () => { organizationService = mock(); providerService = mock(); accountService = mockAccountServiceWith(userId); + platformUtilsService = mock(); router.url = "/"; router.events = of({}); organizationService.organizations$.mockReturnValue(of([{}] as Organization[])); providerService.getAll.mockResolvedValue([] as Provider[]); + platformUtilsService.isSelfHost.mockReturnValue(false); TestBed.configureTestingModule({ providers: [ @@ -55,6 +59,7 @@ describe("ProductSwitcherService", () => { { provide: OrganizationService, useValue: organizationService }, { provide: ProviderService, useValue: providerService }, { provide: AccountService, useValue: accountService }, + { provide: PlatformUtilsService, useValue: platformUtilsService }, { provide: ActivatedRoute, useValue: { @@ -138,11 +143,31 @@ describe("ProductSwitcherService", () => { }); describe("Admin/Organizations", () => { - it("includes Organizations in other when there are organizations", async () => { + it("includes Organizations with the internal route in other when there are organizations on cloud", async () => { initiateService(); const products = await firstValueFrom(service.products$); + const organizations = products.other.find((p) => p.name === "Organizations"); + expect(organizations).toBeDefined(); + expect(organizations.marketingRoute.route).toBe("/create-organization"); + expect(organizations.marketingRoute.external).toBe(false); + + expect(products.other.find((p) => p.name === "Organizations")).toBeDefined(); + expect(products.bento.find((p) => p.name === "Admin Console")).toBeUndefined(); + }); + + it("includes Organizations with the external route in other when there are organizations on Self-Host", async () => { + platformUtilsService.isSelfHost.mockReturnValue(true); + initiateService(); + + const products = await firstValueFrom(service.products$); + + const organizations = products.other.find((p) => p.name === "Organizations"); + expect(organizations).toBeDefined(); + expect(organizations.marketingRoute.route).toBe("https://bitwarden.com/products/business/"); + expect(organizations.marketingRoute.external).toBe(true); + expect(products.other.find((p) => p.name === "Organizations")).toBeDefined(); expect(products.bento.find((p) => p.name === "Admin Console")).toBeUndefined(); }); diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts index f962879d61a..1cc5c92c120 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts @@ -21,6 +21,7 @@ import { import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/platform/sync"; export type ProductSwitcherItem = { @@ -101,6 +102,7 @@ export class ProductSwitcherService { private i18n: I18nPipe, private syncService: SyncService, private accountService: AccountService, + private platformUtilsService: PlatformUtilsService, ) { this.pollUntilSynced(); } @@ -151,6 +153,16 @@ export class ProductSwitcherService { // TODO: This should be migrated to an Observable provided by the provider service and moved to the combineLatest above. See AC-2092. const providers = await this.providerService.getAll(); + const orgsMarketingRoute = this.platformUtilsService.isSelfHost() + ? { + route: "https://bitwarden.com/products/business/", + external: true, + } + : { + route: "/create-organization", + external: false, + }; + const products = { pm: { name: "Password Manager", @@ -197,10 +209,7 @@ export class ProductSwitcherService { orgs: { name: "Organizations", icon: "bwi-business", - marketingRoute: { - route: "https://bitwarden.com/products/business/", - external: true, - }, + marketingRoute: orgsMarketingRoute, otherProductOverrides: { name: "Share your passwords", supportingText: this.i18n.transform("protectYourFamilyOrBusiness"),