mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 09:13:33 +00:00
[PM-28370] fix defect for self-hosted metadata (#17464)
This commit is contained in:
@@ -1451,7 +1451,7 @@ const safeProviders: SafeProvider[] = [
|
|||||||
safeProvider({
|
safeProvider({
|
||||||
provide: OrganizationMetadataServiceAbstraction,
|
provide: OrganizationMetadataServiceAbstraction,
|
||||||
useClass: DefaultOrganizationMetadataService,
|
useClass: DefaultOrganizationMetadataService,
|
||||||
deps: [BillingApiServiceAbstraction, ConfigService],
|
deps: [BillingApiServiceAbstraction, ConfigService, PlatformUtilsServiceAbstraction],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: BillingAccountProfileStateService,
|
provide: BillingAccountProfileStateService,
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ export abstract class BillingApiServiceAbstraction {
|
|||||||
organizationId: OrganizationId,
|
organizationId: OrganizationId,
|
||||||
): Promise<OrganizationBillingMetadataResponse>;
|
): Promise<OrganizationBillingMetadataResponse>;
|
||||||
|
|
||||||
|
abstract getOrganizationBillingMetadataVNextSelfHost(
|
||||||
|
organizationId: OrganizationId,
|
||||||
|
): Promise<OrganizationBillingMetadataResponse>;
|
||||||
|
|
||||||
abstract getPlans(): Promise<ListResponse<PlanResponse>>;
|
abstract getPlans(): Promise<ListResponse<PlanResponse>>;
|
||||||
|
|
||||||
abstract getPremiumPlan(): Promise<PremiumPlanResponse>;
|
abstract getPremiumPlan(): Promise<PremiumPlanResponse>;
|
||||||
|
|||||||
@@ -62,6 +62,20 @@ export class BillingApiService implements BillingApiServiceAbstraction {
|
|||||||
return new OrganizationBillingMetadataResponse(r);
|
return new OrganizationBillingMetadataResponse(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getOrganizationBillingMetadataVNextSelfHost(
|
||||||
|
organizationId: OrganizationId,
|
||||||
|
): Promise<OrganizationBillingMetadataResponse> {
|
||||||
|
const r = await this.apiService.send(
|
||||||
|
"GET",
|
||||||
|
"/organizations/" + organizationId + "/billing/vnext/self-host/metadata",
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
return new OrganizationBillingMetadataResponse(r);
|
||||||
|
}
|
||||||
|
|
||||||
async getPlans(): Promise<ListResponse<PlanResponse>> {
|
async getPlans(): Promise<ListResponse<PlanResponse>> {
|
||||||
const r = await this.apiService.send("GET", "/plans", null, true, true);
|
const r = await this.apiService.send("GET", "/plans", null, true, true);
|
||||||
return new ListResponse(r, PlanResponse);
|
return new ListResponse(r, PlanResponse);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { BehaviorSubject, firstValueFrom } from "rxjs";
|
|||||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
||||||
import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response";
|
import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
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 { newGuid } from "@bitwarden/guid";
|
||||||
|
|
||||||
import { FeatureFlag } from "../../../enums/feature-flag.enum";
|
import { FeatureFlag } from "../../../enums/feature-flag.enum";
|
||||||
@@ -15,6 +16,7 @@ describe("DefaultOrganizationMetadataService", () => {
|
|||||||
let service: DefaultOrganizationMetadataService;
|
let service: DefaultOrganizationMetadataService;
|
||||||
let billingApiService: jest.Mocked<BillingApiServiceAbstraction>;
|
let billingApiService: jest.Mocked<BillingApiServiceAbstraction>;
|
||||||
let configService: jest.Mocked<ConfigService>;
|
let configService: jest.Mocked<ConfigService>;
|
||||||
|
let platformUtilsService: jest.Mocked<PlatformUtilsService>;
|
||||||
let featureFlagSubject: BehaviorSubject<boolean>;
|
let featureFlagSubject: BehaviorSubject<boolean>;
|
||||||
|
|
||||||
const mockOrganizationId = newGuid() as OrganizationId;
|
const mockOrganizationId = newGuid() as OrganizationId;
|
||||||
@@ -33,11 +35,17 @@ describe("DefaultOrganizationMetadataService", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
billingApiService = mock<BillingApiServiceAbstraction>();
|
billingApiService = mock<BillingApiServiceAbstraction>();
|
||||||
configService = mock<ConfigService>();
|
configService = mock<ConfigService>();
|
||||||
|
platformUtilsService = mock<PlatformUtilsService>();
|
||||||
featureFlagSubject = new BehaviorSubject<boolean>(false);
|
featureFlagSubject = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
configService.getFeatureFlag$.mockReturnValue(featureFlagSubject.asObservable());
|
configService.getFeatureFlag$.mockReturnValue(featureFlagSubject.asObservable());
|
||||||
|
platformUtilsService.isSelfHost.mockReturnValue(false);
|
||||||
|
|
||||||
service = new DefaultOrganizationMetadataService(billingApiService, configService);
|
service = new DefaultOrganizationMetadataService(
|
||||||
|
billingApiService,
|
||||||
|
configService,
|
||||||
|
platformUtilsService,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -142,6 +150,24 @@ describe("DefaultOrganizationMetadataService", () => {
|
|||||||
expect(result3).toEqual(mockResponse1);
|
expect(result3).toEqual(mockResponse1);
|
||||||
expect(result4).toEqual(mockResponse2);
|
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", () => {
|
describe("shareReplay behavior", () => {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { BehaviorSubject, combineLatest, from, Observable, shareReplay, switchMap } from "rxjs";
|
import { BehaviorSubject, combineLatest, from, Observable, shareReplay, switchMap } from "rxjs";
|
||||||
|
|
||||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
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 { FeatureFlag } from "../../../enums/feature-flag.enum";
|
||||||
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
||||||
@@ -17,6 +18,7 @@ export class DefaultOrganizationMetadataService implements OrganizationMetadataS
|
|||||||
constructor(
|
constructor(
|
||||||
private billingApiService: BillingApiServiceAbstraction,
|
private billingApiService: BillingApiServiceAbstraction,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
|
private platformUtilsService: PlatformUtilsService,
|
||||||
) {}
|
) {}
|
||||||
private refreshMetadataTrigger = new BehaviorSubject<void>(undefined);
|
private refreshMetadataTrigger = new BehaviorSubject<void>(undefined);
|
||||||
|
|
||||||
@@ -67,7 +69,9 @@ export class DefaultOrganizationMetadataService implements OrganizationMetadataS
|
|||||||
featureFlagEnabled: boolean,
|
featureFlagEnabled: boolean,
|
||||||
): Promise<OrganizationBillingMetadataResponse> {
|
): Promise<OrganizationBillingMetadataResponse> {
|
||||||
return featureFlagEnabled
|
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);
|
: await this.billingApiService.getOrganizationBillingMetadata(organizationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user