diff --git a/apps/browser/src/vault/popup/guards/clear-vault-state.guard.spec.ts b/apps/browser/src/vault/popup/guards/clear-vault-state.guard.spec.ts new file mode 100644 index 00000000000..7ead8576b37 --- /dev/null +++ b/apps/browser/src/vault/popup/guards/clear-vault-state.guard.spec.ts @@ -0,0 +1,77 @@ +import { TestBed } from "@angular/core/testing"; +import { RouterStateSnapshot } from "@angular/router"; + +import { VaultV2Component } from "../components/vault-v2/vault-v2.component"; +import { VaultPopupItemsService } from "../services/vault-popup-items.service"; +import { VaultPopupListFiltersService } from "../services/vault-popup-list-filters.service"; + +import { clearVaultStateGuard } from "./clear-vault-state.guard"; + +describe("clearVaultStateGuard", () => { + let applyFilterSpy: jest.Mock; + let resetFilterFormSpy: jest.Mock; + + beforeEach(() => { + applyFilterSpy = jest.fn(); + resetFilterFormSpy = jest.fn(); + + TestBed.configureTestingModule({ + providers: [ + { + provide: VaultPopupItemsService, + useValue: { applyFilter: applyFilterSpy }, + }, + { + provide: VaultPopupListFiltersService, + useValue: { resetFilterForm: resetFilterFormSpy }, + }, + ], + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it.each([ + "/view-cipher?cipherId=123", + "/edit-cipher?cipherId=123", + "/clone-cipher?cipherId=123", + "/assign-collections?cipherId=123", + ])("should not clear vault state when viewing or editing a cipher: %s", (url) => { + const nextState = { url } as RouterStateSnapshot; + + const result = TestBed.runInInjectionContext(() => + clearVaultStateGuard({} as VaultV2Component, null, null, nextState), + ); + + expect(result).toBe(true); + expect(applyFilterSpy).not.toHaveBeenCalled(); + expect(resetFilterFormSpy).not.toHaveBeenCalled(); + }); + + it.each(["/settings", "/tabs/settings"])( + "should clear vault state when navigating to non-cipher routes: %s", + (url) => { + const nextState = { url } as RouterStateSnapshot; + + const result = TestBed.runInInjectionContext(() => + clearVaultStateGuard({} as VaultV2Component, null, null, nextState), + ); + + expect(result).toBe(true); + expect(applyFilterSpy).toHaveBeenCalledWith(""); + expect(resetFilterFormSpy).toHaveBeenCalled(); + }, + ); + + it("should not clear vault state when not changing states", () => { + const result = TestBed.runInInjectionContext(() => + clearVaultStateGuard({} as VaultV2Component, null, null, null), + ); + + expect(result).toBe(true); + expect(applyFilterSpy).not.toHaveBeenCalled(); + expect(resetFilterFormSpy).not.toHaveBeenCalled(); + }); +}); diff --git a/apps/browser/src/vault/popup/guards/clear-vault-state.guard.ts b/apps/browser/src/vault/popup/guards/clear-vault-state.guard.ts index e27090180d6..2a87db6e903 100644 --- a/apps/browser/src/vault/popup/guards/clear-vault-state.guard.ts +++ b/apps/browser/src/vault/popup/guards/clear-vault-state.guard.ts @@ -7,7 +7,8 @@ import { VaultPopupListFiltersService } from "../services/vault-popup-list-filte /** * Guard to clear the vault state (search and filter) when navigating away from the vault view. - * This ensures the search and filter state is reset when navigating between different tabs, except viewing a cipher. + * This ensures the search and filter state is reset when navigating between different tabs, + * except viewing or editing a cipher. */ export const clearVaultStateGuard: CanDeactivateFn = ( component: VaultV2Component, @@ -17,7 +18,7 @@ export const clearVaultStateGuard: CanDeactivateFn = ( ) => { const vaultPopupItemsService = inject(VaultPopupItemsService); const vaultPopupListFiltersService = inject(VaultPopupListFiltersService); - if (nextState && !isViewingCipher(nextState.url)) { + if (nextState && !isCipherOpen(nextState.url)) { vaultPopupItemsService.applyFilter(""); vaultPopupListFiltersService.resetFilterForm(); } @@ -25,4 +26,8 @@ export const clearVaultStateGuard: CanDeactivateFn = ( return true; }; -const isViewingCipher = (url: string): boolean => url.includes("view-cipher"); +const isCipherOpen = (url: string): boolean => + url.includes("view-cipher") || + url.includes("assign-collections") || + url.includes("edit-cipher") || + url.includes("clone-cipher");