diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 9dbc6679963..b1215654cfd 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1451,7 +1451,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: OrganizationMetadataServiceAbstraction, useClass: DefaultOrganizationMetadataService, - deps: [BillingApiServiceAbstraction, ConfigService], + deps: [BillingApiServiceAbstraction, ConfigService, PlatformUtilsServiceAbstraction], }), safeProvider({ provide: BillingAccountProfileStateService, diff --git a/libs/common/src/billing/abstractions/billing-api.service.abstraction.ts b/libs/common/src/billing/abstractions/billing-api.service.abstraction.ts index ef01c98ecb5..dcb395ef85c 100644 --- a/libs/common/src/billing/abstractions/billing-api.service.abstraction.ts +++ b/libs/common/src/billing/abstractions/billing-api.service.abstraction.ts @@ -25,6 +25,10 @@ export abstract class BillingApiServiceAbstraction { organizationId: OrganizationId, ): Promise; + abstract getOrganizationBillingMetadataVNextSelfHost( + organizationId: OrganizationId, + ): Promise; + abstract getPlans(): Promise>; abstract getPremiumPlan(): Promise; diff --git a/libs/common/src/billing/services/billing-api.service.ts b/libs/common/src/billing/services/billing-api.service.ts index 673d4a9784e..ae6913e545c 100644 --- a/libs/common/src/billing/services/billing-api.service.ts +++ b/libs/common/src/billing/services/billing-api.service.ts @@ -62,6 +62,20 @@ export class BillingApiService implements BillingApiServiceAbstraction { return new OrganizationBillingMetadataResponse(r); } + async getOrganizationBillingMetadataVNextSelfHost( + organizationId: OrganizationId, + ): Promise { + const r = await this.apiService.send( + "GET", + "/organizations/" + organizationId + "/billing/vnext/self-host/metadata", + null, + true, + true, + ); + + return new OrganizationBillingMetadataResponse(r); + } + async getPlans(): Promise> { const r = await this.apiService.send("GET", "/plans", null, true, true); return new ListResponse(r, PlanResponse); diff --git a/libs/common/src/billing/services/organization/organization-metadata.service.spec.ts b/libs/common/src/billing/services/organization/organization-metadata.service.spec.ts index c67f4aed175..a2b012eb161 100644 --- a/libs/common/src/billing/services/organization/organization-metadata.service.spec.ts +++ b/libs/common/src/billing/services/organization/organization-metadata.service.spec.ts @@ -4,6 +4,7 @@ import { BehaviorSubject, firstValueFrom } from "rxjs"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions"; import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { newGuid } from "@bitwarden/guid"; import { FeatureFlag } from "../../../enums/feature-flag.enum"; @@ -15,6 +16,7 @@ describe("DefaultOrganizationMetadataService", () => { let service: DefaultOrganizationMetadataService; let billingApiService: jest.Mocked; let configService: jest.Mocked; + let platformUtilsService: jest.Mocked; let featureFlagSubject: BehaviorSubject; const mockOrganizationId = newGuid() as OrganizationId; @@ -33,11 +35,17 @@ describe("DefaultOrganizationMetadataService", () => { beforeEach(() => { billingApiService = mock(); configService = mock(); + platformUtilsService = mock(); featureFlagSubject = new BehaviorSubject(false); configService.getFeatureFlag$.mockReturnValue(featureFlagSubject.asObservable()); + platformUtilsService.isSelfHost.mockReturnValue(false); - service = new DefaultOrganizationMetadataService(billingApiService, configService); + service = new DefaultOrganizationMetadataService( + billingApiService, + configService, + platformUtilsService, + ); }); afterEach(() => { @@ -142,6 +150,24 @@ describe("DefaultOrganizationMetadataService", () => { expect(result3).toEqual(mockResponse1); expect(result4).toEqual(mockResponse2); }); + + it("calls getOrganizationBillingMetadataVNextSelfHost when feature flag is on and isSelfHost is true", async () => { + platformUtilsService.isSelfHost.mockReturnValue(true); + const mockResponse = createMockMetadataResponse(true, 25); + billingApiService.getOrganizationBillingMetadataVNextSelfHost.mockResolvedValue( + mockResponse, + ); + + const result = await firstValueFrom(service.getOrganizationMetadata$(mockOrganizationId)); + + expect(platformUtilsService.isSelfHost).toHaveBeenCalled(); + expect(billingApiService.getOrganizationBillingMetadataVNextSelfHost).toHaveBeenCalledWith( + mockOrganizationId, + ); + expect(billingApiService.getOrganizationBillingMetadataVNext).not.toHaveBeenCalled(); + expect(billingApiService.getOrganizationBillingMetadata).not.toHaveBeenCalled(); + expect(result).toEqual(mockResponse); + }); }); describe("shareReplay behavior", () => { diff --git a/libs/common/src/billing/services/organization/organization-metadata.service.ts b/libs/common/src/billing/services/organization/organization-metadata.service.ts index fe96f0d984c..5ce87262c4b 100644 --- a/libs/common/src/billing/services/organization/organization-metadata.service.ts +++ b/libs/common/src/billing/services/organization/organization-metadata.service.ts @@ -1,6 +1,7 @@ import { BehaviorSubject, combineLatest, from, Observable, shareReplay, switchMap } from "rxjs"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { FeatureFlag } from "../../../enums/feature-flag.enum"; import { ConfigService } from "../../../platform/abstractions/config/config.service"; @@ -17,6 +18,7 @@ export class DefaultOrganizationMetadataService implements OrganizationMetadataS constructor( private billingApiService: BillingApiServiceAbstraction, private configService: ConfigService, + private platformUtilsService: PlatformUtilsService, ) {} private refreshMetadataTrigger = new BehaviorSubject(undefined); @@ -67,7 +69,9 @@ export class DefaultOrganizationMetadataService implements OrganizationMetadataS featureFlagEnabled: boolean, ): Promise { return featureFlagEnabled - ? await this.billingApiService.getOrganizationBillingMetadataVNext(organizationId) + ? this.platformUtilsService.isSelfHost() + ? await this.billingApiService.getOrganizationBillingMetadataVNextSelfHost(organizationId) + : await this.billingApiService.getOrganizationBillingMetadataVNext(organizationId) : await this.billingApiService.getOrganizationBillingMetadata(organizationId); } }