1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

[PM-24011] Add handler for new policy sync push notification (#17465)

* add handler for new policy sync push notification

* fix story book build failure

* move logic into policy service, fix tests

* add account service

* add missing service to clie
This commit is contained in:
Brandon Treston
2025-12-01 10:21:48 -05:00
committed by GitHub
parent e1d14ca7bd
commit b9d5724312
11 changed files with 131 additions and 8 deletions

View File

@@ -4,6 +4,8 @@ import { BehaviorSubject, bufferCount, firstValueFrom, ObservedValueOf, of, Subj
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports
import { LogoutReason } from "@bitwarden/auth/common";
import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
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";
@@ -42,6 +44,7 @@ describe("NotificationsService", () => {
let webPushNotificationConnectionService: MockProxy<WebPushConnectionService>;
let authRequestAnsweringService: MockProxy<AuthRequestAnsweringServiceAbstraction>;
let configService: MockProxy<ConfigService>;
let policyService: MockProxy<InternalPolicyService>;
let activeAccount: BehaviorSubject<ObservedValueOf<AccountService["activeAccount$"]>>;
let accounts: BehaviorSubject<ObservedValueOf<AccountService["accounts$"]>>;
@@ -71,6 +74,7 @@ describe("NotificationsService", () => {
webPushNotificationConnectionService = mock<WorkerWebPushConnectionService>();
authRequestAnsweringService = mock<AuthRequestAnsweringServiceAbstraction>();
configService = mock<ConfigService>();
policyService = mock<InternalPolicyService>();
// For these tests, use the active-user implementation (feature flag disabled)
configService.getFeatureFlag$.mockImplementation(() => of(true));
@@ -123,6 +127,7 @@ describe("NotificationsService", () => {
webPushNotificationConnectionService,
authRequestAnsweringService,
configService,
policyService,
);
});
@@ -391,5 +396,67 @@ describe("NotificationsService", () => {
expect(logoutCallback).not.toHaveBeenCalled();
});
});
describe("NotificationType.SyncPolicy", () => {
it("should call policyService.syncPolicy with the policy from the notification", async () => {
const mockPolicy = {
id: "policy-id",
organizationId: "org-id",
type: PolicyType.TwoFactorAuthentication,
enabled: true,
data: { test: "data" },
};
policyService.syncPolicy.mockResolvedValue();
const notification = new NotificationResponse({
type: NotificationType.SyncPolicy,
payload: { policy: mockPolicy },
contextId: "different-app-id",
});
await sut["processNotification"](notification, mockUser1);
expect(policyService.syncPolicy).toHaveBeenCalledTimes(1);
expect(policyService.syncPolicy).toHaveBeenCalledWith(
expect.objectContaining({
id: mockPolicy.id,
organizationId: mockPolicy.organizationId,
type: mockPolicy.type,
enabled: mockPolicy.enabled,
data: mockPolicy.data,
}),
);
});
it("should handle SyncPolicy notification with minimal policy data", async () => {
const mockPolicy = {
id: "policy-id-2",
organizationId: "org-id-2",
type: PolicyType.RequireSso,
enabled: false,
};
policyService.syncPolicy.mockResolvedValue();
const notification = new NotificationResponse({
type: NotificationType.SyncPolicy,
payload: { policy: mockPolicy },
contextId: "different-app-id",
});
await sut["processNotification"](notification, mockUser1);
expect(policyService.syncPolicy).toHaveBeenCalledTimes(1);
expect(policyService.syncPolicy).toHaveBeenCalledWith(
expect.objectContaining({
id: mockPolicy.id,
organizationId: mockPolicy.organizationId,
type: mockPolicy.type,
enabled: mockPolicy.enabled,
}),
);
});
});
});
});