UNPKG

passbolt-styleguide

Version:

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

425 lines (375 loc) 18.5 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 FilterResourcesByFolders in regard of specifications */ import { defaultProps, foldersMock } from "./FilterResourcesByFolders.test.data"; import { ResourceWorkspaceFilterTypes } from "../../../contexts/ResourceWorkspaceContext"; import FilterResourcesByRootFolderContextualMenu from "./FilterResourcesByRootFolderContextualMenu"; import FilterResourcesByFoldersPage from "./FilterResourcesByFolders.test.page"; import { defaultResourcesDtos } from "../../../../shared/models/entity/resource/resourcesCollection.test.data"; import FilterResourcesByFoldersItemContextualMenu from "./FilterResourcesByFoldersItemContextualMenu"; import { defaultResourceWorkspaceContext } from "../../../contexts/ResourceWorkspaceContext.test.data"; import NotifyError from "../../Common/Error/NotifyError/NotifyError"; import { TEST_RESOURCE_TYPE_V5_DEFAULT } from "../../../../shared/models/entity/resourceType/resourceTypeEntity.test.data"; import ActionAbortedMissingMetadataKeys from "../../Metadata/ActionAbortedMissingMetadataKeys/ActionAbortedMissingMetadataKeys"; import { defaultUserDto } from "../../../../shared/models/entity/user/userEntity.test.data"; import { v4 as uuidv4 } from "uuid"; import { defaultResourceDto } from "../../../../shared/models/entity/resource/resourceEntity.test.data"; beforeEach(() => { jest.resetModules(); }); describe("See Folders", () => { let page; // The page to test against const props = defaultProps(); // The props to pass const requestMockImpl = jest.fn((message, data) => data); const mockContextRequest = (context, implementation) => jest.spyOn(props.context.port, "request").mockImplementation(implementation); mockContextRequest(props.context, requestMockImpl); describe("As LU I see the folders", () => { /** * Given an organization with 5 Folders * Then I should see the 5 Folders on the left sidebar * And I should see the Folders sorted alphabetically * And I should be able to see each Folder name */ beforeEach(() => { page = new FilterResourcesByFoldersPage(props); }); it("As LU I should collapse the folder tree area", async () => { expect.assertions(5); expect(page.filterResourcesByFolders.exists()).toBeTruthy(); expect(page.filterResourcesByFolders.displayFolderList).toBeTruthy(); await page.filterResourcesByFolders.toggleExpanded(); expect(page.filterResourcesByFolders.displayFolderList).toBeFalsy(); await page.filterResourcesByFolders.toggleExpanded(); expect(page.filterResourcesByFolders.displayFolderList).toBeTruthy(); expect(page.filterResourcesByFolders.rootFolderName).toBe("My workspace"); }); it("As LU I should see all folders name", async () => { expect.assertions(12); expect(page.filterResourcesByFolders.exists()).toBeTruthy(); expect(page.filterResourcesByFoldersItem.exists()).toBeTruthy(); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(6); expect(page.filterResourcesByFoldersItem.count).toBe(8); expect(page.filterResourcesByFoldersItem.name(1)).toBe("1. Test"); expect(page.filterResourcesByFoldersItem.name(2)).toBe("2. Test"); expect(page.filterResourcesByFoldersItem.name(3)).toBe("10. Test"); expect(page.filterResourcesByFoldersItem.name(4)).toBe("Accounting"); expect(page.filterResourcesByFoldersItem.name(5)).toBe("ParentCertificates"); expect(page.filterResourcesByFoldersItem.name(6)).toBe("Certificates"); expect(page.filterResourcesByFoldersItem.name(7)).toBe("ChildCertificates1"); expect(page.filterResourcesByFoldersItem.name(8)).toBe("ChildCertificates2"); expect(page.filterResourcesByFoldersItem.selectedFolderName).toBe("Accounting"); }); it("As LU I should be able to close folder to hide the child folders", async () => { expect.assertions(2); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(6); expect(page.filterResourcesByFoldersItem.count).toBe(8); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); expect(page.filterResourcesByFoldersItem.count).toBe(5); }); it("As LU I should be able to filter by root folder", async () => { expect.assertions(1); await page.title.click(); expect(props.history.push).toHaveBeenCalledWith(`/app/passwords`, { filter: { type: ResourceWorkspaceFilterTypes.ROOT_FOLDER }, }); }); it("As LU I should be able to open a contextual menu for root folder with the more button", async () => { expect.assertions(1); await page.filterResourcesByFolders.openContextualMenuWithButton; expect(props.contextualMenuContext.show).toHaveBeenCalledWith(FilterResourcesByRootFolderContextualMenu, { className: "right", left: 0, top: 19, onBeforeHide: expect.any(Function), }); }); it("As LU I should be able to open a contextual menu for root folder with right click", async () => { expect.assertions(1); await page.filterResourcesByFolders.openContextualMenuWithRightClick; expect(props.contextualMenuContext.show).toHaveBeenCalledWith(FilterResourcesByRootFolderContextualMenu, {}); }); it("As LU I should be able to open a contextual menu for a folder with right click on a child folder", async () => { expect.assertions(1); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.openContextualMenuWithRightClick(6); expect(props.contextualMenuContext.show).toHaveBeenCalledWith(FilterResourcesByFoldersItemContextualMenu, { folder: foldersMock[2], }); }); it("As LU I should be able to drag and drop a folder on the root folder", async () => { expect.assertions(3); await page.filterResourcesByFoldersItem.dragStartOnFolder(1); await page.filterResourcesByFoldersItem.dragEndOnFolder(1); await page.filterResourcesByFolders.onDragOver; await page.filterResourcesByFolders.onDragLeave; await page.filterResourcesByFolders.onDragOver; await page.filterResourcesByFolders.onDrop; expect(props.dragContext.onDragStart).toHaveBeenCalled(); expect(props.context.port.request).toHaveBeenCalledWith( "passbolt.folders.move-by-id", "3ed65efd-7c41-5906-9c02-71e2d95951db", null, ); expect(props.dragContext.onDragEnd).toHaveBeenCalled(); }); it("As LU I should be able to drag and drop a folder on another folder", async () => { expect.assertions(2); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.dragStartOnFolder(5); await page.filterResourcesByFoldersItem.dragEndOnFolder(5); await page.filterResourcesByFoldersItem.onDropFolder(4); expect(props.dragContext.onDragStart).toHaveBeenCalled(); expect(props.context.port.request).toHaveBeenCalledWith( "passbolt.folders.move-by-id", "3ed65efd-7c41-5906-9c02-71e2d95951db", foldersMock[0].id, ); }); it("As LU I should throw an error dialog if somethings went wrong when a folder is dropped", async () => { expect.assertions(2); const error = new Error("ERROR"); jest.spyOn(props.context.port, "request").mockImplementationOnce(() => { throw error; }); const page = new FilterResourcesByFoldersPage(props); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.dragStartOnFolder(5); await page.filterResourcesByFoldersItem.dragEndOnFolder(5); await page.filterResourcesByFoldersItem.onDropFolder(4); // Throw dialog general error message expect(props.context.port.request).toHaveBeenCalledWith( "passbolt.folders.move-by-id", "3ed65efd-7c41-5906-9c02-71e2d95951db", foldersMock[0].id, ); expect(props.dialogContext.open).toHaveBeenCalledWith(NotifyError, { error: error }); }); it("As LU I should be able to open and close folder to see or not the child folders", async () => { expect.assertions(3); expect(page.filterResourcesByFoldersItem.count).toBe(5); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); expect(page.filterResourcesByFoldersItem.count).toBe(6); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); expect(page.filterResourcesByFoldersItem.count).toBe(5); }); }); describe("As LU I should be able to drag and drop resources on folders", () => { it("As LU I should be able to drag and drop resources on the root folder", async () => { expect.assertions(2); const resources = defaultResourcesDtos(); const props = defaultProps({ dragContext: { dragging: true, draggedItems: { folders: [], resources: resources, }, onDragStart: jest.fn(), onDragEnd: jest.fn(), }, }); props.context.port.addRequestListener( "passbolt.resources.move-by-ids", async (resourcesIds, destinationFolder) => { expect(destinationFolder).toBeNull(); expect(resourcesIds).toStrictEqual(resources.map((r) => r.id)); }, ); const page = new FilterResourcesByFoldersPage(props); await page.filterResourcesByFolders.onDragOver; await page.filterResourcesByFolders.onDragLeave; await page.filterResourcesByFolders.onDragOver; await page.filterResourcesByFolders.onDrop; }); it("As LU I should be able to drag and drop resources on another folder", async () => { expect.assertions(4); const resources = defaultResourcesDtos(); const props = defaultProps({ dragContext: { dragging: true, draggedItems: { folders: [], resources: resources, }, onDragStart: jest.fn(), onDragEnd: jest.fn(), }, }); props.context.port.addRequestListener( "passbolt.resources.move-by-ids", async (resourcesIds, destinationFolder) => { expect(destinationFolder).toStrictEqual(foldersMock[4].id); expect(resourcesIds).toStrictEqual(resources.map((r) => r.id)); }, ); const page = new FilterResourcesByFoldersPage(props); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(6); await page.filterResourcesByFoldersItem.dragStartOnFolder(7); await page.filterResourcesByFoldersItem.dragEndOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.dragLeaveOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.onDropFolder(7); expect(props.dragContext.onDragStart).toHaveBeenCalled(); expect(props.dragContext.onDragEnd).toHaveBeenCalled(); }); it("As LU I should not be able to drag and drop personal resources v5 on a shared folder if I have missing keys", async () => { expect.assertions(3); const resources = [ defaultResourceDto(), defaultResourceDto({ personal: true, resource_type_id: TEST_RESOURCE_TYPE_V5_DEFAULT }), ]; const props = defaultProps({ dragContext: { dragging: true, draggedItems: { folders: [], resources: resources, }, onDragStart: jest.fn(), onDragEnd: jest.fn(), }, }); props.context.loggedInUser = defaultUserDto({ missing_metadata_key_ids: [uuidv4()] }, { withRole: true }); const page = new FilterResourcesByFoldersPage(props); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(6); await page.filterResourcesByFoldersItem.dragStartOnFolder(7); await page.filterResourcesByFoldersItem.dragEndOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.dragLeaveOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.onDropFolder(7); expect(props.dragContext.onDragStart).toHaveBeenCalled(); expect(props.dragContext.onDragEnd).toHaveBeenCalled(); expect(props.dialogContext.open).toHaveBeenNthCalledWith(1, ActionAbortedMissingMetadataKeys); }); it("As LU I should not be able to drag and drop a folder on a shared folder if I have missing keys", async () => { expect.assertions(3); const props = defaultProps(); props.context.loggedInUser = defaultUserDto({ missing_metadata_key_ids: [uuidv4()] }, { withRole: true }); const page = new FilterResourcesByFoldersPage(props); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(6); await page.filterResourcesByFoldersItem.dragStartOnFolder(7); await page.filterResourcesByFoldersItem.dragEndOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.dragLeaveOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.onDropFolder(7); expect(props.dragContext.onDragStart).toHaveBeenCalled(); expect(props.dragContext.onDragEnd).toHaveBeenCalled(); expect(props.dialogContext.open).toHaveBeenNthCalledWith(1, ActionAbortedMissingMetadataKeys); }); it("As LU I should throw an error dialog if somethings went wrong when a resource is dropped", async () => { expect.assertions(2); const resources = defaultResourcesDtos(); const props = defaultProps({ dragContext: { dragging: true, draggedItems: { folders: [], resources: resources, }, onDragStart: jest.fn(), onDragEnd: jest.fn(), }, }); const error = new Error("ERROR"); jest.spyOn(props.context.port, "request").mockImplementationOnce(() => { throw error; }); const page = new FilterResourcesByFoldersPage(props); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(5); await page.filterResourcesByFoldersItem.toggleDisplayChildFolders(6); await page.filterResourcesByFoldersItem.dragStartOnFolder(7); await page.filterResourcesByFoldersItem.dragEndOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.dragLeaveOnFolder(7); await page.filterResourcesByFoldersItem.dragOverOnFolder(7); await page.filterResourcesByFoldersItem.onDropFolder(7); // Throw dialog general error message expect(props.context.port.request).toHaveBeenCalledWith( "passbolt.resources.move-by-ids", resources.map((resource) => resource.id), foldersMock[4].id, ); expect(props.dialogContext.open).toHaveBeenCalledWith(NotifyError, { error: error }); }); }); describe("As LU I should see the Folder section open to the selected folder with parent open", () => { const props = defaultProps({ resourceWorkspaceContext: defaultResourceWorkspaceContext({ filter: { type: ResourceWorkspaceFilterTypes.FOLDER, payload: { folder: foldersMock[5], }, }, }), match: { params: { filterByFolderId: foldersMock[5].id, }, }, }); /** * Given an organization with 5 Folders with a child folder selected * Then I should see the Folder selected with parent folder open */ beforeEach(() => { page = new FilterResourcesByFoldersPage(props); }); it("As LU I should see selected folder name with parents open", () => { expect.assertions(7); expect(page.filterResourcesByFoldersItem.count).toBe(5); expect(page.filterResourcesByFoldersItem.name(1)).toBe("1. Test"); expect(page.filterResourcesByFoldersItem.name(2)).toBe("2. Test"); expect(page.filterResourcesByFoldersItem.name(3)).toBe("10. Test"); expect(page.filterResourcesByFoldersItem.name(4)).toBe("Accounting"); expect(page.filterResourcesByFoldersItem.name(5)).toBe("ParentCertificates"); expect(page.filterResourcesByFoldersItem.selectedFolderName).toBe("1. Test"); }); }); describe("As LU I should see the Folder section empty", () => { const props = defaultProps(); props.context.folders = []; /** * Given an organization with 0 Folders * Then I should see the Folder section empty */ beforeEach(() => { page = new FilterResourcesByFoldersPage(props); }); it("I should see the Folders section empty", () => { expect(page.filterResourcesByFolders.isEmpty()).toBeTruthy(); }); }); describe("As LU I see a loading feedback in the section when the folders are not yet fetched", () => { const props = defaultProps(); props.context.folders = null; beforeEach(() => { page = new FilterResourcesByFoldersPage(props); }); it("I should see the loading message “Retrieving folders", async () => { expect(page.filterResourcesByFolders.isLoading()).toBeTruthy(); }); }); });