mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: use org-scoped roles for organization groups and members e2e tests (#16691)
This commit is contained in:
+29
-3
@@ -3,8 +3,8 @@ import { expect } from "@playwright/test";
|
||||
import { API, type DeploymentConfig } from "api/api";
|
||||
import type { SerpentOption } from "api/typesGenerated";
|
||||
import { formatDuration, intervalToDuration } from "date-fns";
|
||||
import { coderPort } from "./constants";
|
||||
import { findSessionToken, randomName } from "./helpers";
|
||||
import { coderPort, defaultPassword } from "./constants";
|
||||
import { type LoginOptions, findSessionToken, randomName } from "./helpers";
|
||||
|
||||
let currentOrgId: string;
|
||||
|
||||
@@ -29,14 +29,40 @@ export const createUser = async (...orgIds: string[]) => {
|
||||
email: `${name}@coder.com`,
|
||||
username: name,
|
||||
name: name,
|
||||
password: "s3cure&password!",
|
||||
password: defaultPassword,
|
||||
login_type: "password",
|
||||
organization_ids: orgIds,
|
||||
user_status: null,
|
||||
});
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
export const createOrganizationMember = async (
|
||||
orgRoles: Record<string, string[]>,
|
||||
): Promise<LoginOptions> => {
|
||||
const name = randomName();
|
||||
const user = await API.createUser({
|
||||
email: `${name}@coder.com`,
|
||||
username: name,
|
||||
name: name,
|
||||
password: defaultPassword,
|
||||
login_type: "password",
|
||||
organization_ids: Object.keys(orgRoles),
|
||||
user_status: null,
|
||||
});
|
||||
|
||||
for (const [org, roles] of Object.entries(orgRoles)) {
|
||||
API.updateOrganizationMemberRoles(org, user.id, roles);
|
||||
}
|
||||
|
||||
return {
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
password: defaultPassword,
|
||||
};
|
||||
};
|
||||
|
||||
export const createGroup = async (orgId: string) => {
|
||||
const name = randomName();
|
||||
const group = await API.createGroup(orgId, {
|
||||
|
||||
@@ -15,6 +15,7 @@ export const coderdPProfPort = 6062;
|
||||
|
||||
// The name of the organization that should be used by default when needed.
|
||||
export const defaultOrganizationName = "coder";
|
||||
export const defaultOrganizationId = "00000000-0000-0000-0000-000000000000";
|
||||
export const defaultPassword = "SomeSecurePassword!";
|
||||
|
||||
// Credentials for users
|
||||
@@ -30,6 +31,12 @@ export const users = {
|
||||
email: "templateadmin@coder.com",
|
||||
roles: ["Template Admin"],
|
||||
},
|
||||
userAdmin: {
|
||||
username: "user-admin",
|
||||
password: defaultPassword,
|
||||
email: "useradmin@coder.com",
|
||||
roles: ["User Admin"],
|
||||
},
|
||||
auditor: {
|
||||
username: "auditor",
|
||||
password: defaultPassword,
|
||||
|
||||
+28
-1
@@ -61,7 +61,7 @@ export function requireTerraformProvisioner() {
|
||||
test.skip(!requireTerraformTests);
|
||||
}
|
||||
|
||||
type LoginOptions = {
|
||||
export type LoginOptions = {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
@@ -1127,3 +1127,30 @@ export async function createOrganization(page: Page): Promise<{
|
||||
|
||||
return { name, displayName, description };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param organization organization name
|
||||
* @param user user email or username
|
||||
*/
|
||||
export async function addUserToOrganization(
|
||||
page: Page,
|
||||
organization: string,
|
||||
user: string,
|
||||
roles: string[] = [],
|
||||
): Promise<void> {
|
||||
await page.goto(`/organizations/${organization}`, {
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
|
||||
await page.getByPlaceholder("User email or username").fill(user);
|
||||
await page.getByRole("option", { name: user }).click();
|
||||
await page.getByRole("button", { name: "Add user" }).click();
|
||||
const addedRow = page.locator("tr", { hasText: user });
|
||||
await expect(addedRow).toBeVisible();
|
||||
|
||||
await addedRow.getByLabel("Edit user roles").click();
|
||||
for (const role of roles) {
|
||||
await page.getByText(role).click();
|
||||
}
|
||||
await page.mouse.click(10, 10); // close the popover by clicking outside of it
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ import { expect, test } from "@playwright/test";
|
||||
import {
|
||||
createGroup,
|
||||
createOrganization,
|
||||
createOrganizationMember,
|
||||
createUser,
|
||||
setupApiCalls,
|
||||
} from "../api";
|
||||
import { defaultOrganizationName } from "../constants";
|
||||
import { defaultOrganizationId, defaultOrganizationName } from "../constants";
|
||||
import { expectUrl } from "../expectUrl";
|
||||
import { login, randomName, requiresLicense } from "../helpers";
|
||||
import { beforeCoderTest } from "../hooks";
|
||||
@@ -32,6 +33,11 @@ test("create group", async ({ page }) => {
|
||||
|
||||
// Create a new organization
|
||||
const org = await createOrganization();
|
||||
const orgUserAdmin = await createOrganizationMember({
|
||||
[org.id]: ["organization-user-admin"],
|
||||
});
|
||||
|
||||
await login(page, orgUserAdmin);
|
||||
await page.goto(`/organizations/${org.name}`);
|
||||
|
||||
// Navigate to groups page
|
||||
@@ -64,8 +70,7 @@ test("create group", async ({ page }) => {
|
||||
await expect(addedRow).toBeVisible();
|
||||
|
||||
// Ensure we can't add a user who isn't in the org
|
||||
const otherOrg = await createOrganization();
|
||||
const personToReject = await createUser(otherOrg.id);
|
||||
const personToReject = await createUser(defaultOrganizationId);
|
||||
await page
|
||||
.getByPlaceholder("User email or username")
|
||||
.fill(personToReject.email);
|
||||
@@ -93,8 +98,12 @@ test("change quota settings", async ({ page }) => {
|
||||
// Create a new organization and group
|
||||
const org = await createOrganization();
|
||||
const group = await createGroup(org.id);
|
||||
const orgUserAdmin = await createOrganizationMember({
|
||||
[org.id]: ["organization-user-admin"],
|
||||
});
|
||||
|
||||
// Go to settings
|
||||
await login(page, orgUserAdmin);
|
||||
await page.goto(`/organizations/${org.name}/groups/${group.name}`);
|
||||
await page.getByRole("button", { name: "Settings", exact: true }).click();
|
||||
expectUrl(page).toHavePathName(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { setupApiCalls } from "../api";
|
||||
import {
|
||||
addUserToOrganization,
|
||||
createOrganization,
|
||||
createUser,
|
||||
login,
|
||||
@@ -18,7 +19,7 @@ test("add and remove organization member", async ({ page }) => {
|
||||
requiresLicense();
|
||||
|
||||
// Create a new organization
|
||||
const { displayName } = await createOrganization(page);
|
||||
const { name: orgName, displayName } = await createOrganization(page);
|
||||
|
||||
// Navigate to members page
|
||||
await page.getByRole("link", { name: "Members" }).click();
|
||||
@@ -26,17 +27,14 @@ test("add and remove organization member", async ({ page }) => {
|
||||
|
||||
// Add a user to the org
|
||||
const personToAdd = await createUser(page);
|
||||
await page.getByPlaceholder("User email or username").fill(personToAdd.email);
|
||||
await page.getByRole("option", { name: personToAdd.email }).click();
|
||||
await page.getByRole("button", { name: "Add user" }).click();
|
||||
const addedRow = page.locator("tr", { hasText: personToAdd.email });
|
||||
await expect(addedRow).toBeVisible();
|
||||
// This must be done as an admin, because you can't assign a role that has more
|
||||
// permissions than you, even if you have the ability to assign roles.
|
||||
await addUserToOrganization(page, orgName, personToAdd.email, [
|
||||
"Organization User Admin",
|
||||
"Organization Template Admin",
|
||||
]);
|
||||
|
||||
// Give them a role
|
||||
await addedRow.getByLabel("Edit user roles").click();
|
||||
await page.getByText("Organization User Admin").click();
|
||||
await page.getByText("Organization Template Admin").click();
|
||||
await page.mouse.click(10, 10); // close the popover by clicking outside of it
|
||||
const addedRow = page.locator("tr", { hasText: personToAdd.email });
|
||||
await expect(addedRow.getByText("Organization User Admin")).toBeVisible();
|
||||
await expect(addedRow.getByText("+1 more")).toBeVisible();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user