UNPKG

passbolt-styleguide

Version:

Passbolt styleguide contains common styling assets used by the different sites, plugin, etc.

463 lines (404 loc) 21.8 kB
/** * Passbolt ~ Open source password manager for teams * Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) * * Licensed under GNU Affero General Public License version 3 of the or any later version. * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.passbolt.com Passbolt(tm) * @since 2.11.0 */ /** * Unit tests on ResourceWorkspaceContext in regard of specifications */ import { defaultProps, defaultAppContext } from "./ResourceWorkspaceContext.test.data"; import ResourceWorkspaceContextPage from "./ResourceWorkspaceContext.test.page"; import { ResourceWorkspaceFilterTypes } from "./ResourceWorkspaceContext"; import { waitFor } from "@testing-library/react"; import { waitForTrue } from "../../../test/utils/waitFor"; import { act } from "react"; describe("Resource Workspace Context", () => { let page; // The page to test against const context = defaultAppContext(); // The applicative context const totalResourcesCount = context.resources.length; const mockContextRequest = (context, implementation) => jest.spyOn(context.port, "request").mockImplementation(implementation); beforeEach(() => { jest.resetAllMocks(); jest.resetModules(); const props = defaultProps(); // The applicative context page = new ResourceWorkspaceContextPage(context, props); }); describe("As LU I should have the appropriate search filter at any time", () => { it("AS LU I should have an initial filter set to NONE", () => { const props = defaultProps(); const page = new ResourceWorkspaceContextPage(context, props); expect(page.filter).toBeDefined(); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.NONE); }); it("AS LU I should have home filter when I went to /app/passwords without filter", async () => { await page.goToAllItems(); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.ALL); }); it("AS LU I should have an SHARED-WITH-ME filter when I went to /app/passwords with such a filter", async () => { await page.goToShareWithMe(); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.SHARED_WITH_ME); }); it("AS LU I should have an EXPIRED filter when I went to /app/passwords/filter/expried with such a filter", async () => { await page.goToExpired(); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.EXPIRED); }); it("AS LU I should have an ITEMS-I-OWN filter when I went to /app/passwords with such a filter", async () => { await page.goToItemsIOwn(); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.ITEMS_I_OWN); }); it("AS LU I should have an PRIVATE filter when I went to /app/passwords with such a filter", async () => { await page.goToPrivate(); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.PRIVATE); }); it("AS LU I should have an FAVORITE filter when I went to /app/passwords with such a filter", async () => { await page.goToFavorite(); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.FAVORITE); }); it("AS LU I should have an TEXT filter when I went to /app/passwords with such a filter", async () => { await page.goToText("some text"); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.TEXT); }); it("AS LU I should have an GROUP filter when I went to /app/passwords with such a filter", async () => { await page.goToGroup({ group: { id: "some group id" } }); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.GROUP); }); it("AS LU I should have an TAG filter when I went to /app/passwords with such a filter", async () => { await page.goToTag({ tag: { id: "some tag id" } }); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.TAG); }); it("AS LU I should have an FOLDER filter when I went to /app/folders/{folder-id} with such a filter", async () => { await page.goToFolder(context.folders[0]); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.FOLDER); }); it("AS LU I should have an ROOT-FOLDER filter when I went to /app/folders/{folder-id} with such a filter", async () => { await page.goToRootFolder(); await waitForTrue(() => page.filter.type !== ResourceWorkspaceFilterTypes.ALL); expect(page.filter.type).toBe(ResourceWorkspaceFilterTypes.ROOT_FOLDER); }); }); describe("As LU I should have the appropriate search filtered results at any time", () => { it("AS LU I should have all resources when the filter is ALL-ITEMS", async () => { await page.goToAllItems(); expect(page.filteredResources).toStrictEqual(context.resources); }); it("AS LU I should have resources shared with me when the filter is SHARED-WITH-ME", async () => { const expectedResourcesCount = 6; await page.goToShareWithMe(); expect(page.filteredResources).toHaveLength(expectedResourcesCount); }); it("AS LU I should have my own resources when the filter is ITEMS-I-OWN", async () => { const expectedResourcesCount = 5; await page.goToItemsIOwn(); expect(page.filteredResources).toHaveLength(expectedResourcesCount); }); it("AS LU I should have my own resources when the filter is PRIVATE", async () => { const expectedResourcesCount = 2; await page.goToPrivate(); expect(page.filteredResources).toHaveLength(expectedResourcesCount); }); it("AS LU I should have my favorite resources when the filter is FAVORITE", async () => { const expectedResourcesCount = 1; await page.goToFavorite(); expect(page.filteredResources).toHaveLength(expectedResourcesCount); }); it("AS LU I should have resources matching a text when the filter is TEXT", async () => { const expectedResourcesCount = 1; await page.goToText("owned"); await waitForTrue(() => page.filteredResources.length !== totalResourcesCount); expect(page.filteredResources).toHaveLength(expectedResourcesCount); expect(page.filteredResources[0].metadata.name).toBe("Resource owned"); }); it("AS LU I should have resources matching a text when the filter is TEXT in folder name", async () => { const expectedResourcesCount = 1; await page.goToText("Folder searchable"); await waitForTrue(() => page.filteredResources.length !== totalResourcesCount); expect(page.filteredResources).toHaveLength(expectedResourcesCount); expect(page.filteredResources[0].metadata.name).toBe("Resource in folder"); }); it("AS LU I should have resources belonged to a group when the filter is GROUP", async () => { expect.hasAssertions(); const mockGroupResources = context.resources.slice(0, 3); const expectedResourcesCount = mockGroupResources.length; const leadershipTeamGroup = { group: { id: "516c2db6-0aed-52d8-854f-b3f3499995e7" } }; context.port.addRequestListener("passbolt.resources.find-all-ids-by-is-shared-with-group", async () => mockGroupResources.map((group) => group.id), ); context.port.addRequestListener("passbolt.resources.update-local-storage", async () => { if (page.filter.type === ResourceWorkspaceFilterTypes.GROUP) { throw new Error("'passbolt.resources.update-local-storage' should have been called after filtering by GROUP"); } }); await page.goToGroup(leadershipTeamGroup); await waitFor(() => { expect(page.filteredResources).toHaveLength(expectedResourcesCount); }); }); it("AS LU I should have resources with a specific tag when the filter is TAG", async () => { const expectedResourcesCount = 1; await page.goToTag({ tag: context.resources[2].tags[0] }); expect(page.filteredResources).toHaveLength(expectedResourcesCount); }); it("AS LU I should have resources belonged to a folder if the filter is FOLDER", async () => { expect.assertions(2); const expectedResourcesCount = 1; context.port.addRequestListener("passbolt.resources.update-local-storage-by-folder-parent-id", async () => {}); jest.spyOn(context.port, "request"); await page.goToFolder(context.folders[0]); expect(page.filteredResources).toHaveLength(expectedResourcesCount); expect(context.port.request).toHaveBeenCalledWith( "passbolt.resources.update-local-storage-by-folder-parent-id", context.folders[0].id, ); }); it("AS LU I should have resources belonged to a root folder the filter is ROOT-FOLDER", async () => { const expectedResourcesCount = 10; await page.goToRootFolder(); expect(page.filteredResources).toHaveLength(expectedResourcesCount); }); }); describe("As LU I should have the appropriate selected resources at any time", () => { it("As LU I should have an initial set of selected resources to empty", () => { expect(page.selectedResources).toBeDefined(); expect(page.selectedResources).toHaveLength(0); }); it("As LU I should have all resources as selected when the All Selection event has been fired", async () => { await page.goToAllItems(); act(() => page.selectAll()); expect(page.selectedResources).toHaveLength(context.resources.length); }); it("As LU I should have none resources as selected when the None Selection event has been fired", async () => { await page.goToAllItems(); page.selectAll(); page.selectNone(); expect(page.selectedResources).toHaveLength(0); }); it("As LU I should have one selected resource when the Single Selection event has been fired", async () => { await page.goToAllItems(); const resourceToSelect = context.resources[0]; act(() => page.select(resourceToSelect)); expect(page.selectedResources).toHaveLength(1); expect(page.selectedResources[0]).toBe(resourceToSelect); }); it("As LU I should have multiple resources as selected when the Multiple Selection event has been fired", async () => { expect.assertions(3); await page.goToAllItems(); const resourcesToSelect = [context.resources[0], context.resources[3]]; page.selectMultiple(resourcesToSelect); expect(page.selectedResources).toHaveLength(2); expect(page.selectedResources[0]).toBe(context.resources[0]); expect(page.selectedResources[1]).toBe(context.resources[3]); }); it("As LU I should have a range of selected resources when the Range Selection event has been fired", async () => { await page.goToAllItems(); const resourcesToSelect = [context.resources[0], context.resources[3]]; page.selectRange(resourcesToSelect); const expectResourceMatch = (resource, index) => expect(resource).toBe(context.resources[index]); expect(page.selectedResources).toHaveLength(4); page.selectedResources.slice(0, 4).forEach(expectResourceMatch); }); }); describe("As LU I should have the appropriate details at any time", () => { it("As LU, I should detail a folder when a folder is selected as filter", async () => { const folder = context.folders[0]; await page.goToFolder(folder); expect(page.details.folder).toBe(folder); expect(page.lockDisplayDetail).toBeTruthy(); }); it("As LU, I should detail a resource when a resource is selected", async () => { expect.assertions(2); const resource = context.resources[0]; await page.goToAllItems(); page.select(resource); await waitForTrue(() => page.details?.resource !== null); expect(page.details.resource).toEqual(resource); expect(page.lockDisplayDetail).toBeTruthy(); }); it("As LU, I should detail nothing when the detail visibility lock is removed", async () => { expect.assertions(2); const resource = context.resources[0]; page.toggleLockDetails(); page.select(resource); await waitForTrue(() => page.details?.resource !== null); expect(page.details.resource).toEqual(resource); expect(page.lockDisplayDetail).toBeFalsy(); }); it("As LU, I should detail nothing when several resources are selected", async () => { await page.goToAllItems(); page.selectAll(); expect(page.details.folder).toBeNull(); expect(page.details.resource).toBeNull(); }); }); describe("As LU I be able to follow a resource uri", () => { it("As LU I be able to follow a safe resource uri", async () => { const resource = context.resources[0]; jest.spyOn(context.port, "request"); await page.goToResourceUri(resource.metadata.uris[0]); expect(context.port.request).toHaveBeenCalledWith("passbolt.tabs.open-resource-uri", "https://passbolt.com/"); }); it("As LU I not be able to follow an unsafe resource uri", async () => { const resource = context.resources[0]; resource.uri = "javascript://mars-attack"; jest.spyOn(context.port, "request"); await page.goToResourceUri(resource.uri); expect(context.port.request).not.toHaveBeenCalledWith("passbolt.tabs.open-resource-uri", expect.anything()); }); }); describe("As LU I should be able to load resource columns setting", () => { it("As LU I should be able to load resource columns setting empty", async () => { expect.assertions(2); await page.goToAllItems(); const defaultColumnsSetting = [ { id: "favorite", label: "Favorite", position: 1, show: true }, { id: "icon", label: "Icon", position: 2, show: true }, { id: "name", label: "Name", position: 3, show: true }, { id: "username", label: "Username", position: 4, show: true }, { id: "password", label: "Password", position: 5, show: true }, { id: "totp", label: "TOTP", position: 6, show: true }, { id: "uri", label: "URI", position: 7, show: true }, { id: "tags", label: "Tags", position: 8, show: true }, { id: "expired", label: "Expiry", position: 9, show: true }, { id: "modified", label: "Modified", position: 10, show: true }, { id: "location", label: "Location", position: 11, show: true }, ]; expect(page.columnsResourceSetting.items.length).toStrictEqual(11); expect(page.columnsResourceSetting.toDto()).toStrictEqual(defaultColumnsSetting); }); it("As LU I should be able to load resource columns setting", async () => { expect.assertions(3); const columnsSetting = [ { id: "favorite", label: "Favorite", position: 1, show: true }, { id: "icon", label: "Icon", position: 2, show: true }, { id: "name", label: "Name", position: 3, show: true }, { id: "username", label: "Username", position: 4, show: true }, { id: "password", label: "Password", position: 5, show: true }, { id: "totp", label: "TOTP", position: 6, show: true }, { id: "uri", label: "URI", position: 7, show: true }, { id: "tags", label: "Tags", position: 8, show: true }, { id: "expired", label: "Expiry", position: 9, show: true }, { id: "modified", label: "Modified", position: 10, show: true }, { id: "location", label: "Location", position: 11, show: true }, ]; const sorter = { propertyName: "name", asc: true, }; const gridSetting = { columns_setting: columnsSetting, sorter: sorter, }; mockContextRequest(context, (path) => { const isGridSettingRequest = path === "passbolt.resources.get-grid-setting"; return isGridSettingRequest ? gridSetting : context.port.request; }); await page.goToAllItems(); await page.goToRootFolder(); expect(page.columnsResourceSetting.items.length).toStrictEqual(11); expect(page.columnsResourceSetting.toDto()).toStrictEqual(columnsSetting); expect(page.sorter.toDto()).toStrictEqual(sorter); }); }); describe("As LU I should be able to show/hide a resource column", () => { it("As LU I should be able to show a resource column", async () => { expect.assertions(1); await page.goToAllItems(); act(() => page.onChangeColumnView("name", true)); expect(page.columnsResourceSetting.items[1].show).toBeTruthy(); }); it("As LU I should be able to hide a resource column", async () => { expect.assertions(1); await page.goToAllItems(); act(() => page.onChangeColumnView("name", false)); expect(page.columnsResourceSetting.items[2].show).toBeFalsy(); }); }); describe("As LU I should be able to update the resource columns setting", () => { it("As LU I should be able to show a resource column", async () => { expect.assertions(2); const columnsSetting = [ { id: "favorite", label: "Favorite", position: 1, width: 20 }, { id: "username", label: "Username", position: 2, width: 200 }, { id: "password", label: "Password", position: 3, width: 100 }, { id: "totp", label: "TOTP", position: 5, width: 190 }, { id: "uri", label: "URI", position: 4, width: 300 }, { id: "modified", label: "Modified", position: 5, width: 250 }, ]; const mergedColumnsSetting = [ { id: "favorite", label: "Favorite", position: 1, width: 20, show: true }, { id: "icon", label: "Icon", position: 2, show: true }, { id: "name", label: "Name", position: 3, show: false }, { id: "username", label: "Username", position: 2, width: 200, show: true }, { id: "password", label: "Password", position: 3, width: 100, show: true }, { id: "totp", label: "TOTP", position: 5, width: 190, show: true }, { id: "uri", label: "URI", position: 4, width: 300, show: true }, { id: "tags", label: "Tags", position: 8, show: true }, { id: "expired", label: "Expiry", position: 9, show: true }, { id: "modified", label: "Modified", position: 5, width: 250, show: true }, { id: "location", label: "Location", position: 11, show: true }, ]; await page.goToAllItems(); page.onChangeColumnView("name", false); page.onChangeColumnsSettings(columnsSetting); expect(page.columnsResourceSetting.length).toStrictEqual(11); expect(page.columnsResourceSetting.toDto()).toStrictEqual(mergedColumnsSetting); }); }); describe("As LU I should be able to reset the resource columns setting", () => { it("As LU I should be able to reset the resource column settings", async () => { expect.assertions(22); await page.goToAllItems(); page.onChangeColumnView("favorite", false); page.onChangeColumnView("icon", false); page.onChangeColumnView("name", false); page.onChangeColumnView("username", false); page.onChangeColumnView("password", false); page.onChangeColumnView("totp", false); page.onChangeColumnView("uri", false); page.onChangeColumnView("tags", false); page.onChangeColumnView("modified", false); page.onChangeColumnView("expired", false); page.onChangeColumnView("location", false); expect(page.columnsResourceSetting.items[0].show).toBeFalsy(); expect(page.columnsResourceSetting.items[1].show).toBeFalsy(); expect(page.columnsResourceSetting.items[2].show).toBeFalsy(); expect(page.columnsResourceSetting.items[3].show).toBeFalsy(); expect(page.columnsResourceSetting.items[4].show).toBeFalsy(); expect(page.columnsResourceSetting.items[5].show).toBeFalsy(); expect(page.columnsResourceSetting.items[6].show).toBeFalsy(); expect(page.columnsResourceSetting.items[7].show).toBeFalsy(); expect(page.columnsResourceSetting.items[8].show).toBeFalsy(); expect(page.columnsResourceSetting.items[9].show).toBeFalsy(); expect(page.columnsResourceSetting.items[10].show).toBeFalsy(); await act(async () => page.resetColumnsSettings()); expect(page.columnsResourceSetting.items[0].show).toBeTruthy(); expect(page.columnsResourceSetting.items[1].show).toBeTruthy(); expect(page.columnsResourceSetting.items[2].show).toBeTruthy(); expect(page.columnsResourceSetting.items[3].show).toBeTruthy(); expect(page.columnsResourceSetting.items[4].show).toBeTruthy(); expect(page.columnsResourceSetting.items[5].show).toBeTruthy(); expect(page.columnsResourceSetting.items[6].show).toBeTruthy(); expect(page.columnsResourceSetting.items[7].show).toBeTruthy(); expect(page.columnsResourceSetting.items[8].show).toBeTruthy(); expect(page.columnsResourceSetting.items[9].show).toBeTruthy(); expect(page.columnsResourceSetting.items[10].show).toBeTruthy(); }); }); });