UNPKG

passbolt-styleguide

Version:

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

437 lines (344 loc) 17.2 kB
/** * Passbolt ~ Open source password manager for teams * Copyright (c) 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) Passbolt SA (https://www.passbolt.com) * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.passbolt.com Passbolt(tm) * @since 5.11.0 */ import { defaultProps, defaultSsoSettings, withAzureSsoSettings, withGoogleSsoSettings, withOAuth2SsoSettings, withAdfsSsoSettings, withPingOneSsoSettings, } from "./AdminSsoContext.test.data"; import { AdminSsoContextProvider } from "./AdminSsoContext"; describe("AdminSsoContext", () => { let adminSsoContext; const props = defaultProps(); beforeEach(() => { jest.resetAllMocks(); adminSsoContext = new AdminSsoContextProvider(props); const setStateMock = (state, callback) => { adminSsoContext.state = Object.assign(adminSsoContext.state, state); if (callback) { callback(); } }; jest.spyOn(adminSsoContext, "setState").mockImplementation(setStateMock); }); describe("AdminSsoContextProvider::loadSsoConfiguration", () => { it("should load Azure SSO configuration and store it in its state", async () => { expect.assertions(4); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.state.isLoaded).toBe(true); expect(adminSsoContext.state.ssoConfig.provider).toBe("azure"); expect(adminSsoContext.state.ssoConfig.client_id).toBe(azureSettings.data.client_id); expect(adminSsoContext.formSettings).not.toBeNull(); }); it("should load Google SSO configuration and store it in its state", async () => { expect.assertions(3); const googleSettings = withGoogleSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => googleSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.state.isLoaded).toBe(true); expect(adminSsoContext.state.ssoConfig.provider).toBe("google"); expect(adminSsoContext.state.ssoConfig.client_id).toBe(googleSettings.data.client_id); }); it("should load OAuth2 SSO configuration and store it in its state", async () => { expect.assertions(3); const oauth2Settings = withOAuth2SsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => oauth2Settings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.state.isLoaded).toBe(true); expect(adminSsoContext.state.ssoConfig.provider).toBe("oauth2"); expect(adminSsoContext.state.ssoConfig.client_id).toBe(oauth2Settings.data.client_id); }); it("should load ADFS SSO configuration and store it in its state", async () => { expect.assertions(3); const adfsSettings = withAdfsSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => adfsSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.state.isLoaded).toBe(true); expect(adminSsoContext.state.ssoConfig.provider).toBe("adfs"); expect(adminSsoContext.state.ssoConfig.client_id).toBe(adfsSettings.data.client_id); }); it("should load PingOne SSO configuration and store it in its state", async () => { expect.assertions(4); const pingOneSettings = withPingOneSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => pingOneSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.state.isLoaded).toBe(true); expect(adminSsoContext.state.ssoConfig.provider).toBe("pingone"); expect(adminSsoContext.state.ssoConfig.client_id).toBe(pingOneSettings.data.client_id); expect(adminSsoContext.state.ssoConfig.environment_id).toBe(pingOneSettings.data.environment_id); }); it("should load configuration with no provider and store null ssoConfig", async () => { expect.assertions(2); const noProviderSettings = defaultSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => noProviderSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.state.isLoaded).toBe(true); expect(adminSsoContext.state.ssoConfig).toBeNull(); }); it("should open error dialog on API error", async () => { expect.assertions(2); const error = new Error("API error"); props.context.port.addRequestListener("passbolt.sso.get-current", () => { throw error; }); const result = await adminSsoContext.loadSsoConfiguration(); expect(result).toStrictEqual({}); expect(props.dialogContext.open).toHaveBeenCalled(); }); }); describe("AdminSsoContextProvider::getSsoProviderFormEntity", () => { it("should return null for unknown provider", () => { expect.assertions(1); const result = adminSsoContext.getSsoProviderFormEntity({ provider: "unknown" }); expect(result).toBeNull(); }); it("should return null for missing provider", () => { expect.assertions(1); const result = adminSsoContext.getSsoProviderFormEntity({}); expect(result).toBeNull(); }); it("should return null for null settings", () => { expect.assertions(1); const result = adminSsoContext.getSsoProviderFormEntity(null); expect(result).toBeNull(); }); }); describe("AdminSsoContextProvider::setValue", () => { it("should update the ssoConfig when a value is set", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.setValue("client_id", "new-client-id"); expect(adminSsoContext.state.ssoConfig.client_id).toBe("new-client-id"); expect(adminSsoContext.formSettings.client_id).toBe("new-client-id"); }); it("should trigger validation if form has already been validated", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.validateData(); const validateSpy = jest.spyOn(adminSsoContext, "validateData"); adminSsoContext.setValue("client_id", "updated-client-id"); expect(validateSpy).toHaveBeenCalledTimes(1); }); }); describe("AdminSsoContextProvider::hasFormChanged", () => { it("should return false when no changes have been made", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.hasFormChanged()).toBe(false); }); it("should return true when changes have been made", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.setValue("client_id", "new-client-id"); expect(adminSsoContext.hasFormChanged()).toBe(true); }); it("should return true when sso is disabled but was previously configured", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.disableSso(); expect(adminSsoContext.hasFormChanged()).toBe(true); }); it("should return false when neither original nor form settings exist", () => { expect.assertions(1); expect(adminSsoContext.hasFormChanged()).toBe(false); }); }); describe("AdminSsoContextProvider::changeProvider", () => { it("should change the provider and cache the previous config", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.changeProvider({ id: "google" }); expect(adminSsoContext.state.ssoConfig.provider).toBe("google"); expect(adminSsoContext.cachedSsoConfig["azure"]).not.toBeUndefined(); }); it("should restore cached config when switching back to a previous provider", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); const originalClientId = adminSsoContext.state.ssoConfig.client_id; adminSsoContext.changeProvider({ id: "google" }); adminSsoContext.changeProvider({ id: "azure" }); expect(adminSsoContext.state.ssoConfig.provider).toBe("azure"); expect(adminSsoContext.state.ssoConfig.client_id).toBe(originalClientId); }); it("should not change provider if disabled", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.changeProvider({ id: "google", disabled: true }); expect(adminSsoContext.state.ssoConfig.provider).toBe("azure"); }); }); describe("AdminSsoContextProvider::disableSso", () => { it("should set ssoConfig to null and cache the current config", async () => { expect.assertions(3); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.disableSso(); expect(adminSsoContext.state.ssoConfig).toBeNull(); expect(adminSsoContext.formSettings).toBeNull(); expect(adminSsoContext.cachedSsoConfig["azure"]).not.toBeUndefined(); }); }); describe("AdminSsoContextProvider::isSsoConfigActivated", () => { it("should return false when no config is set", () => { expect.assertions(1); expect(adminSsoContext.isSsoConfigActivated()).toBe(false); }); it("should return true when a config is loaded", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.isSsoConfigActivated()).toBe(true); }); }); describe("AdminSsoContextProvider::canDeleteSettings", () => { it("should return false when no existing config and sso is not disabled", () => { expect.assertions(1); expect(adminSsoContext.canDeleteSettings()).toBe(false); }); it("should return true when existing config is disabled", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.disableSso(); expect(adminSsoContext.canDeleteSettings()).toBe(true); }); }); describe("AdminSsoContextProvider::validateData", () => { it("should return true for valid data", async () => { expect.assertions(1); const googleSettings = withGoogleSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => googleSettings); await adminSsoContext.loadSsoConfiguration(); expect(adminSsoContext.validateData()).toBe(true); }); it("should return false for invalid data", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.setValue("client_id", ""); expect(adminSsoContext.validateData()).toBe(false); }); it("should set hasBeenValidated state to true", async () => { expect.assertions(1); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.validateData(); expect(adminSsoContext.state.hasBeenValidated).toBe(true); }); }); describe("AdminSsoContextProvider::getErrors", () => { it("should return null before validation", () => { expect.assertions(1); expect(adminSsoContext.getErrors()).toBeNull(); }); it("should return errors after validation with invalid data", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.setValue("client_id", ""); adminSsoContext.validateData(); const errors = adminSsoContext.getErrors(); expect(errors).not.toBeNull(); expect(errors.hasError("client_id")).toBe(true); }); }); describe("AdminSsoContextProvider::saveAndTestConfiguration", () => { it("should save draft and open test dialog", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); const draftResponse = { ...azureSettings, id: "draft-id" }; props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); props.context.port.addRequestListener("passbolt.sso.save-draft", () => draftResponse); await adminSsoContext.loadSsoConfiguration(); await adminSsoContext.saveAndTestConfiguration(); expect(props.dialogContext.open).toHaveBeenCalled(); expect(adminSsoContext.state.ssoConfig.provider).toBe("azure"); }); it("should handle save draft error", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); props.context.port.addRequestListener("passbolt.sso.save-draft", () => { throw new Error("Save error"); }); await adminSsoContext.loadSsoConfiguration(); await adminSsoContext.saveAndTestConfiguration(); expect(props.dialogContext.open).toHaveBeenCalled(); expect(adminSsoContext.state.processing).toBe(false); }); }); describe("AdminSsoContextProvider::deleteSettings", () => { it("should delete settings and reset state", async () => { expect.assertions(3); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); props.context.port.addRequestListener("passbolt.sso.delete-settings", () => {}); await adminSsoContext.loadSsoConfiguration(); await adminSsoContext.deleteSettings(); expect(adminSsoContext.state.ssoConfig).toBeNull(); expect(adminSsoContext.formSettings).toBeNull(); expect(adminSsoContext.originalSettings).toBeNull(); }); it("should handle delete error", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); props.context.port.addRequestListener("passbolt.sso.delete-settings", () => { throw new Error("Delete error"); }); await adminSsoContext.loadSsoConfiguration(); await adminSsoContext.deleteSettings(); expect(props.dialogContext.open).toHaveBeenCalled(); expect(adminSsoContext.state.processing).toBe(false); }); }); describe("AdminSsoContextProvider::handleSettingsActivation", () => { it("should mark SSO config as existing and update original settings", async () => { expect.assertions(2); const azureSettings = withAzureSsoSettings(); props.context.port.addRequestListener("passbolt.sso.get-current", () => azureSettings); await adminSsoContext.loadSsoConfiguration(); adminSsoContext.handleSettingsActivation(); expect(adminSsoContext.isSsoConfigExisting).toBe(true); expect(adminSsoContext.originalSettings).not.toBeNull(); }); }); });