Skip to content

Commit 59582cf

Browse files
fix: unable to add or edit user from admin page and add tests (calcom#23871)
* fix * Update UserForm.tsx * test: add e2e tests for admin user creation and editing - Add test for successful user creation via /settings/admin/users/add - Add test for successful user editing via /settings/admin/users/{id} - Tests verify form submission, API responses, and database changes - Follow Cal.com e2e testing patterns with admin authentication - Use Playwright for end-to-end form interaction testing Co-Authored-By: anik@cal.com <adhabal2002@gmail.com> * Update admin-users.e2e.ts * Update admin-users.e2e.ts * update * tweak --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 5c70060 commit 59582cf

3 files changed

Lines changed: 80 additions & 4 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { expect } from "@playwright/test";
2+
3+
import { test } from "./lib/fixtures";
4+
5+
test.describe.configure({ mode: "parallel" });
6+
7+
test.describe("Admin Users Management", () => {
8+
test("should add a new user successfully", async ({ page, users }) => {
9+
const adminUser = await users.create({
10+
role: "ADMIN",
11+
});
12+
13+
await adminUser.apiLogin();
14+
15+
await page.goto("/settings/admin/users/add");
16+
17+
await page.waitForLoadState();
18+
19+
await page.fill('input[name="name"]', "Test User");
20+
await page.fill('input[name="username"]', "testuser");
21+
await page.fill('input[name="email"]', "testuser@example.com");
22+
await page.fill('input[name="bio"]', "Test user bio");
23+
24+
await page.locator('[data-testid="timezone-select"] div').first().click();
25+
26+
const responsePromise = page.waitForResponse((response) =>
27+
response.url().includes("/api/trpc/users/add")
28+
);
29+
30+
await page.click('button[type="submit"]');
31+
32+
const response = await responsePromise;
33+
expect(response.status()).toBe(200);
34+
35+
await page.waitForURL("/settings/admin/users");
36+
});
37+
38+
test("should edit an existing user successfully", async ({ page, users }) => {
39+
const adminUser = await users.create({
40+
role: "ADMIN",
41+
});
42+
43+
const userToEdit = await users.create({
44+
name: "Edit User",
45+
username: "edituser",
46+
});
47+
48+
await adminUser.apiLogin();
49+
50+
await page.goto(`/settings/admin/users/${userToEdit.id}/edit`);
51+
52+
await page.waitForLoadState();
53+
54+
await expect(page.locator('input[name="name"]')).toHaveValue("Edit User");
55+
56+
await page.fill('input[name="name"]', "Updated User");
57+
58+
const responsePromise = page.waitForResponse((response) =>
59+
response.url().includes("/api/trpc/users/update")
60+
);
61+
62+
await page.click('button[type="submit"]');
63+
64+
const response = await responsePromise;
65+
expect(response.status()).toBe(200);
66+
67+
await page.waitForURL("/settings/admin/users");
68+
});
69+
});

packages/features/ee/users/components/UserForm.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,14 @@ export const UserForm = ({
7878

7979
const form = useForm<FormValues>({
8080
defaultValues: {
81-
avatarUrl: defaultValues?.avatarUrl,
81+
avatarUrl: defaultValues?.avatarUrl || null,
8282
name: defaultValues?.name,
8383
username: defaultValues?.username,
8484
email: defaultValues?.email,
8585
bio: defaultValues?.bio,
86-
theme: defaultValues?.theme,
87-
defaultScheduleId: defaultValues?.defaultScheduleId,
88-
allowDynamicBooking: defaultValues?.allowDynamicBooking,
86+
theme: defaultValues?.theme || null,
87+
defaultScheduleId: defaultValues?.defaultScheduleId || null,
88+
allowDynamicBooking: defaultValues?.allowDynamicBooking ?? true,
8989
locale: {
9090
value: defaultLocale,
9191
label: new Intl.DisplayNames(defaultLocale, { type: "language" }).of(defaultLocale) || "",

packages/features/ee/users/schemas/userBodySchema.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { optionToValueSchema } from "@calcom/prisma/zod-utils";
12
import { UserSchema } from "@calcom/prisma/zod/modelSchema/UserSchema";
23

34
export const userBodySchema = UserSchema.pick({
@@ -15,4 +16,10 @@ export const userBodySchema = UserSchema.pick({
1516
locale: true,
1617
timeFormat: true,
1718
allowDynamicBooking: true,
19+
}).extend({
20+
role: optionToValueSchema(UserSchema.shape.role),
21+
identityProvider: optionToValueSchema(UserSchema.shape.identityProvider),
22+
weekStart: optionToValueSchema(UserSchema.shape.weekStart),
23+
locale: optionToValueSchema(UserSchema.shape.locale),
24+
timeFormat: optionToValueSchema(UserSchema.shape.timeFormat),
1825
});

0 commit comments

Comments
 (0)