mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 14:53:33 +00:00
[PM-27059] Browser: Retain vault filters when editing a cipher from the dropdown (#16910)
* Skip clearing vault filters if a cipher is being edited * add unit tests for clearVaultStateGuard
This commit is contained in:
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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.
|
* 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<VaultV2Component> = (
|
export const clearVaultStateGuard: CanDeactivateFn<VaultV2Component> = (
|
||||||
component: VaultV2Component,
|
component: VaultV2Component,
|
||||||
@@ -17,7 +18,7 @@ export const clearVaultStateGuard: CanDeactivateFn<VaultV2Component> = (
|
|||||||
) => {
|
) => {
|
||||||
const vaultPopupItemsService = inject(VaultPopupItemsService);
|
const vaultPopupItemsService = inject(VaultPopupItemsService);
|
||||||
const vaultPopupListFiltersService = inject(VaultPopupListFiltersService);
|
const vaultPopupListFiltersService = inject(VaultPopupListFiltersService);
|
||||||
if (nextState && !isViewingCipher(nextState.url)) {
|
if (nextState && !isCipherOpen(nextState.url)) {
|
||||||
vaultPopupItemsService.applyFilter("");
|
vaultPopupItemsService.applyFilter("");
|
||||||
vaultPopupListFiltersService.resetFilterForm();
|
vaultPopupListFiltersService.resetFilterForm();
|
||||||
}
|
}
|
||||||
@@ -25,4 +26,8 @@ export const clearVaultStateGuard: CanDeactivateFn<VaultV2Component> = (
|
|||||||
return true;
|
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");
|
||||||
|
|||||||
Reference in New Issue
Block a user