UNPKG

passbolt-styleguide

Version:

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

356 lines (306 loc) 15.3 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 ShareDialog in regard of specifications */ import ShareDialogPage from "./ShareDialog.test.page"; import { autocompleteResult, defaultAppContext, defaultProps, folders, mockResultsFolders, mockResultsResources, mockResultsResourcesAndFolders, resources } from "./ShareDialog.test.data"; import {ActionFeedbackContext} from "../../contexts/ActionFeedbackContext"; import PassboltApiFetchError from "../../../shared/lib/Error/PassboltApiFetchError"; import {waitFor} from "@testing-library/react"; import NotifyError from "../Common/Error/NotifyError/NotifyError"; beforeAll(() => { global.scrollTo = jest.fn(); }); beforeEach(() => { jest.resetModules(); jest.useFakeTimers(); }); afterEach(() => { jest.clearAllTimers(); }); describe("As Lu I should see the share dialog", () => { let page; // The page to test against const context = defaultAppContext(); // The applicative context const props = defaultProps(); // The props to pass const mockContextRequest = implementation => jest.spyOn(context.port, 'request').mockImplementation(implementation); describe('As LU I can start sharing resources', () => { const shareDialogProps = { resourcesIds: ["8e3874ae-4b40-590b-968a-418f704b9d9a", "daaf057e-7fc3-5537-a8a9-e8c151890878", "c8b93000-56b3-5a16-8048-c579d1babbd7"], }; /** * I should see the share dialog */ beforeEach(async() => { const requestResourcesMockImpl = path => mockResultsResources[path]; mockContextRequest(requestResourcesMockImpl); context.setContext({shareDialogProps}); page = new ShareDialogPage(context, props); }); it('As LU I see a success toaster message after sharing resources to users and groups with success', async() => { expect.assertions(18); expect(context.port.request).toHaveBeenCalledWith('passbolt.share.get-resources', shareDialogProps.resourcesIds); expect(page.exists()).toBeTruthy(); expect(page.title).toBe('Share 3 resources'); expect(page.count).toBe(11); const requestKeyInfoMockImpl = () => ({ fingerprint: "079D6F4FDA3BFDC2D8E562D8AA44B1DA4BFB36B6" }); mockContextRequest(requestKeyInfoMockImpl); await page.searchName("adm"); jest.runOnlyPendingTimers(); await waitFor(() => { if (!page.userOrGroupAutocomplete(1)) { throw new Error("Page is not ready yet."); } }); await page.selectUserOrGroup(1); expect(page.warningMessage).toBe('Click save to apply your pending changes.'); expect(page.count).toBe(12); expect(page.aroName(1)).toBe('Ada Lovelace'); expect(page.aroDetails(1)).toBe('ada@passbolt.com'); expect(page.aroName(2)).toBe('Betty Holberton'); expect(page.aroDetails(2)).toBe('betty@passbolt.com'); expect(page.aroName(3)).toBe('Board'); expect(page.aroDetails(3)).toBe('Group'); expect(page.aroName(12)).toBe('Admin User'); expect(page.aroDetails(12)).toBe('admin@passbolt.com'); expect(page.selectRights(12).textContent).toBe('can read'); const requestMockImpl = jest.fn(); mockContextRequest(requestMockImpl); jest.spyOn(ActionFeedbackContext._currentValue, 'displaySuccess').mockImplementation(() => {}); await page.savePermissions(); const permissionDto = [{"aco": "Resource", "aco_foreign_key": shareDialogProps.resourcesIds[0], "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}, {"aco": "Resource", "aco_foreign_key": shareDialogProps.resourcesIds[1], "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}, {"aco": "Resource", "aco_foreign_key": "690b6e40-f371-579c-b0c6-86e8ef383adc", "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}, {"aco": "Resource", "aco_foreign_key": "ecf0ed85-3bfc-5f45-b11d-74e9a86aa313", "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}]; expect(context.port.request).toHaveBeenCalledWith("passbolt.share.resources.save", resources, permissionDto); expect(ActionFeedbackContext._currentValue.displaySuccess).toHaveBeenCalledWith('The permissions have been changed successfully.'); expect(props.onClose).toBeCalled(); }); it('As LU I can remove a permission', async() => { expect.assertions(2); expect(page.count).toBe(11); await page.selectRemovePermission(1); expect(page.count).toBe(10); }); it('As LU I should see a processing feedback while submitting the form', async() => { const requestAutocompleteResultMockImpl = jest.fn(() => autocompleteResult); mockContextRequest(requestAutocompleteResultMockImpl); await page.searchName("adm"); jest.runOnlyPendingTimers(); await waitFor(() => { if (!page.userOrGroupAutocomplete(1)) { throw new Error("Page is not ready yet."); } }); await page.selectUserOrGroup(1); // Mock the request function to make it the expected result let updateResolve; const requestMockImpl = jest.fn(() => new Promise(resolve => { updateResolve = resolve; })); // Mock the request function to make it the expected result mockContextRequest(requestMockImpl); page.savePermissionsWithoutWait(); // API calls are made on submit, wait they are resolved. await waitFor(() => { expect(page.shareNameInput.getAttribute("disabled")).not.toBeNull(); expect(page.selectRights(1).className).toBe("selected-value disabled"); expect(page.removeAro(1).className).toBe('remove-item button button-transparent disabled'); expect(page.cancelButton.className).toBe('cancel disabled'); expect(page.saveButton.getAttribute("disabled")).not.toBeNull(); expect(page.saveButton.className).toBe("button primary disabled processing"); updateResolve(); }); }); it('As LU I shouldn’t be able to submit the form if there is no owner', async() => { expect.assertions(2); await page.selectFirstItemRights(1); expect(page.errorMessage).toBe('Please make sure there is at least one owner.'); expect(page.saveButton.getAttribute("disabled")).not.toBeNull(); }); it('As LU I can stop sharing resources by clicking on the cancel button', async() => { expect.assertions(2); expect(page.exists()).toBeTruthy(); await page.click(page.cancelButton); expect(props.onClose).toBeCalled(); }); it('As LU I can stop sharing resources by closing the dialog', async() => { expect.assertions(2); expect(page.exists()).toBeTruthy(); await page.click(page.dialogClose); expect(props.onClose).toBeCalled(); }); it('As LU I can stop sharing resources with the keyboard (escape)', async() => { expect.assertions(2); expect(page.exists()).toBeTruthy(); await page.escapeKey(page.dialogClose); expect(props.onClose).toBeCalled(); }); it('As LU I should see an error dialog if the submit operation fails for an unexpected reason', async() => { expect.assertions(1); const requestAutocompleteResultMockImpl = jest.fn(() => autocompleteResult); mockContextRequest(requestAutocompleteResultMockImpl); await page.searchName("adm"); jest.runOnlyPendingTimers(); await waitFor(() => { if (!page.userOrGroupAutocomplete(1)) { throw new Error("Page is not ready yet."); } }); await page.selectUserOrGroup(1); // Mock the request function to make it return an error. const error = new PassboltApiFetchError("Jest simulate API error."); jest.spyOn(context.port, 'request').mockImplementationOnce(() => { throw error; }); await page.savePermissions(); // Throw general error message expect(props.dialogContext.open).toHaveBeenCalledWith(NotifyError, {error: error}); }); }); describe('As LU I can start sharing one resources', () => { const shareDialogProps = { resourcesIds: ["8e3874ae-4b40-590b-968a-418f704b9d9a"], }; /** * I should see the share dialog */ beforeEach(async() => { const requestResourcesMockImpl = path => mockResultsResources[path]; mockContextRequest(requestResourcesMockImpl); context.setContext({shareDialogProps}); page = new ShareDialogPage(context, props); }); it('As LU I see a success toaster message after sharing one resource to users and groups with success', async() => { expect.assertions(12); expect(context.port.request).toHaveBeenCalledWith('passbolt.share.get-resources', shareDialogProps.resourcesIds); expect(page.exists()).toBeTruthy(); expect(page.title).toBe('Share resource'); expect(page.subtitle).toBe('apache'); expect(page.count).toBe(11); const requestAutocompleteResultMockImpl = jest.fn(() => autocompleteResult); mockContextRequest(requestAutocompleteResultMockImpl); await page.searchName("adm"); jest.runOnlyPendingTimers(); await waitFor(() => { if (!page.userOrGroupAutocomplete(1)) { throw new Error("Page is not ready yet."); } }); await page.selectUserOrGroup(1); expect(page.count).toBe(12); expect(page.aroName(12)).toBe('Admin User'); expect(page.aroDetails(12)).toBe('admin@passbolt.com'); expect(page.selectRights(12).textContent).toBe('can read'); const requestMockImpl = jest.fn(); mockContextRequest(requestMockImpl); jest.spyOn(ActionFeedbackContext._currentValue, 'displaySuccess').mockImplementation(() => {}); await page.savePermissions(); const permissionDto = [{"aco": "Resource", "aco_foreign_key": shareDialogProps.resourcesIds[0], "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}, {"aco": "Resource", "aco_foreign_key": "daaf057e-7fc3-5537-a8a9-e8c151890878", "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}, {"aco": "Resource", "aco_foreign_key": "690b6e40-f371-579c-b0c6-86e8ef383adc", "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}, {"aco": "Resource", "aco_foreign_key": "ecf0ed85-3bfc-5f45-b11d-74e9a86aa313", "aro": "User", "aro_foreign_key": "d57c10f5-639d-5160-9c81-8a0c6c4ec856", "is_new": true, "type": 1}]; expect(context.port.request).toHaveBeenCalledWith("passbolt.share.resources.save", resources, permissionDto); expect(ActionFeedbackContext._currentValue.displaySuccess).toHaveBeenCalledWith('The permissions have been changed successfully.'); expect(props.onClose).toBeCalled(); }); }); describe('As LU I can start sharing one folder', () => { const shareDialogProps = { foldersIds: ["8e3874ae-4b40-590b-968a-418f704b9d9a"], }; /** * I should see the share dialog */ beforeEach(async() => { const requestResourcesMockImpl = path => mockResultsFolders[path]; mockContextRequest(requestResourcesMockImpl); context.setContext({shareDialogProps}); page = new ShareDialogPage(context, props); }); it('As LU I see a success toaster message after sharing one folder to users and groups with success', async() => { expect.assertions(12); expect(context.port.request).toHaveBeenCalledWith('passbolt.share.get-folders', shareDialogProps.foldersIds); expect(page.exists()).toBeTruthy(); expect(page.title).toBe('Share folder'); expect(page.subtitle).toBe('apache'); expect(page.count).toBe(2); const requestKeyInfoMockImpl = () => ({ fingerprint: "079D6F4FDA3BFDC2D8E562D8AA44B1DA4BFB36B6" }); mockContextRequest(requestKeyInfoMockImpl); await page.searchName("ad"); jest.runOnlyPendingTimers(); await waitFor(() => { if (!page.userOrGroupAutocomplete(2)) { throw new Error("Page is not ready yet."); } }); await page.selectUserOrGroup(2); expect(page.count).toBe(3); expect(page.aroName(3)).toBe('Adele Goldstine'); expect(page.aroDetails(3)).toBe('adele@passbolt.com'); expect(page.selectRights(3).textContent).toBe('can read'); const requestMockImpl = jest.fn(); mockContextRequest(requestMockImpl); jest.spyOn(ActionFeedbackContext._currentValue, 'displaySuccess').mockImplementation(() => {}); await page.savePermissions(); const permissionDto = [{"aco": "Folder", "aco_foreign_key": shareDialogProps.foldersIds[0], "aro": "User", "aro_foreign_key": "af5e1f70-a0ee-5b76-935b-c846f8a6a190", "is_new": true, "type": 1}]; expect(context.port.request).toHaveBeenCalledWith("passbolt.share.folders.save", folders, permissionDto); expect(ActionFeedbackContext._currentValue.displaySuccess).toHaveBeenCalledWith('The permissions have been changed successfully.'); expect(props.onClose).toBeCalled(); }); }); describe('As LU I can\'t start sharing folders and resources at the same time', () => { const shareDialogProps = { resourcesIds: ["8e3874ae-4b40-590b-968a-418f704b9d9a"], foldersIds: ["8e3874ae-4b40-590b-968a-418f704b9d9a"], }; /** * I should see the share dialog */ beforeEach(async() => { const requestResourcesMockImpl = path => mockResultsResourcesAndFolders[path]; mockContextRequest(requestResourcesMockImpl); context.setContext({shareDialogProps}); page = new ShareDialogPage(context, props); }); it('As LU I see a error dialog message after try to sharing folders and resources at the same time', async() => { expect.assertions(3); expect(page.exists()).toBeTruthy(); expect(page.title).toBe('Share 2 items'); const requestAutocompleteResultMockImpl = jest.fn(() => autocompleteResult); mockContextRequest(requestAutocompleteResultMockImpl); await page.searchName("adm"); jest.runOnlyPendingTimers(); await waitFor(() => { if (!page.userOrGroupAutocomplete(1)) { throw new Error("Page is not ready yet."); } }); await page.selectUserOrGroup(1); await page.savePermissions(); // Throw general error message expect(props.dialogContext.open).toHaveBeenCalledWith(NotifyError, {error: new Error("Multi resource and folder share is not implemented.")}); }); }); });