diff --git a/site/e2e/README.md b/site/e2e/README.md index 76af72b17d182..b89bad5cf8782 100644 --- a/site/e2e/README.md +++ b/site/e2e/README.md @@ -55,7 +55,7 @@ code . Enterprise tests require a license key to run. ```shell -export CODER_E2E_ENTERPRISE_LICENSE= +export CODER_E2E_LICENSE= ``` # Debugging tests diff --git a/site/e2e/api.ts b/site/e2e/api.ts index da5a57dee007d..0494467799a97 100644 --- a/site/e2e/api.ts +++ b/site/e2e/api.ts @@ -63,6 +63,35 @@ export const createOrganization = async () => { return org; }; +export const deleteOrganization = async (orgName: string) => { + await API.deleteOrganization(orgName); +}; + +export const createOrganizationWithName = async (name: string) => { + const org = await API.createOrganization({ + name, + display_name: `${name}`, + description: `Org description ${name}`, + icon: "/emojis/1f957.png", + }); + return org; +}; + +export const createOrganizationSyncSettings = async () => { + const settings = await API.patchOrganizationIdpSyncSettings({ + field: "organization-field-test", + mapping: { + "idp-org-1": [ + "fbd2116a-8961-4954-87ae-e4575bd29ce0", + "13de3eb4-9b4f-49e7-b0f8-0c3728a0d2e2", + ], + "idp-org-2": ["fbd2116a-8961-4954-87ae-e4575bd29ce0"], + }, + organization_assign_default: true, + }); + return settings; +}; + export async function verifyConfigFlagBoolean( page: Page, config: DeploymentConfig, diff --git a/site/e2e/tests/deployment/idpOrgSync.spec.ts b/site/e2e/tests/deployment/idpOrgSync.spec.ts new file mode 100644 index 0000000000000..59fccb440400b --- /dev/null +++ b/site/e2e/tests/deployment/idpOrgSync.spec.ts @@ -0,0 +1,157 @@ +import { expect, test } from "@playwright/test"; +import { + createOrganizationSyncSettings, + createOrganizationWithName, + deleteOrganization, + setupApiCalls, +} from "../../api"; +import { requiresLicense } from "../../helpers"; +import { beforeCoderTest } from "../../hooks"; + +test.describe("IdpOrgSyncPage", () => { + test.beforeEach(async ({ page }) => await beforeCoderTest(page)); + + test("add new IdP organization mapping with API", async ({ page }) => { + requiresLicense(); + await setupApiCalls(page); + + await createOrganizationSyncSettings(); + + await page.goto("/deployment/idp-org-sync", { + waitUntil: "domcontentloaded", + }); + + await expect( + page.getByRole("switch", { name: "Assign Default Organization" }), + ).toBeChecked(); + + await expect(page.getByText("idp-org-1")).toBeVisible(); + await expect( + page.getByText("fbd2116a-8961-4954-87ae-e4575bd29ce0").first(), + ).toBeVisible(); + + await expect(page.getByText("idp-org-2")).toBeVisible(); + await expect( + page.getByText("fbd2116a-8961-4954-87ae-e4575bd29ce0").last(), + ).toBeVisible(); + }); + + test("delete a IdP org to coder org mapping row", async ({ page }) => { + requiresLicense(); + await setupApiCalls(page); + await createOrganizationSyncSettings(); + await page.goto("/deployment/idp-org-sync", { + waitUntil: "domcontentloaded", + }); + + await expect(page.getByText("idp-org-1")).toBeVisible(); + await page + .getByRole("button", { name: /delete/i }) + .first() + .click(); + await expect(page.getByText("idp-org-1")).not.toBeVisible(); + await expect( + page.getByText("Organization sync settings updated."), + ).toBeVisible(); + }); + + test("update sync field", async ({ page }) => { + requiresLicense(); + await page.goto("/deployment/idp-org-sync", { + waitUntil: "domcontentloaded", + }); + + const syncField = page.getByRole("textbox", { + name: "Organization sync field", + }); + const saveButton = page.getByRole("button", { name: "Save" }).first(); + + await expect(saveButton).toBeDisabled(); + + await syncField.fill("test-field"); + await expect(saveButton).toBeEnabled(); + + await page.getByRole("button", { name: "Save" }).click(); + + await expect( + page.getByText("Organization sync settings updated."), + ).toBeVisible(); + }); + + test("toggle default organization assignment", async ({ page }) => { + requiresLicense(); + await page.goto("/deployment/idp-org-sync", { + waitUntil: "domcontentloaded", + }); + + const toggle = page.getByRole("switch", { + name: "Assign Default Organization", + }); + await toggle.click(); + + await expect( + page.getByText("Organization sync settings updated."), + ).toBeVisible(); + + await expect(toggle).not.toBeChecked(); + }); + + test("export policy button is enabled when sync settings are present", async ({ + page, + }) => { + requiresLicense(); + await setupApiCalls(page); + + await page.goto("/deployment/idp-org-sync", { + waitUntil: "domcontentloaded", + }); + + const exportButton = page.getByRole("button", { name: /Export Policy/i }); + await createOrganizationSyncSettings(); + + await expect(exportButton).toBeEnabled(); + await exportButton.click(); + }); + + test("add new IdP organization mapping with UI", async ({ page }) => { + requiresLicense(); + await setupApiCalls(page); + + await createOrganizationWithName("developers"); + + await page.goto("/deployment/idp-org-sync", { + waitUntil: "domcontentloaded", + }); + + const idpOrgInput = page.getByLabel("IdP organization name"); + const orgSelector = page.getByPlaceholder("Select organization"); + const addButton = page.getByRole("button", { + name: /Add IdP organization/i, + }); + + await expect(addButton).toBeDisabled(); + + await idpOrgInput.fill("new-idp-org"); + + // Select Coder organization from combobox + await orgSelector.click(); + await page.getByRole("option", { name: "developers" }).click(); + + // Add button should now be enabled + await expect(addButton).toBeEnabled(); + + await addButton.click(); + + // Verify new mapping appears in table + const newRow = page.getByTestId("idp-org-new-idp-org"); + await expect(newRow).toBeVisible(); + await expect(newRow.getByText("new-idp-org")).toBeVisible(); + await expect(newRow.getByText("developers")).toBeVisible(); + + await expect( + page.getByText("Organization sync settings updated."), + ).toBeVisible(); + + await deleteOrganization("developers"); + }); +}); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy