1
0
forked from baron/baron-sso

dev 병합 code check 수정

This commit is contained in:
2026-04-22 17:27:33 +09:00
parent 9e73059d2a
commit c40202f502
18 changed files with 540 additions and 70 deletions

View File

@@ -19,39 +19,50 @@ test.describe("DevFront developer request and management", () => {
});
});
test("user can request developer access when no RP exists", async ({ page }) => {
test("user can request developer access when no RP exists", async ({
page,
}) => {
const state = {
clients: [],
consents: [],
developerRequests: [],
};
await seedAuth(page, "user");
await seedAuth(page, "user");
await installDevApiMock(page, state);
await page.goto("/clients");
// Click Request Button
const requestBtn = page.getByRole('button', { name: /개발자 등록 신청/ });
await requestBtn.waitFor({ state: 'visible' });
// Click request link and open the request modal on the dedicated page
const requestBtn = page.getByRole("button", {
name: /개발자 등록 신청하기|개발자 등록 신청/,
});
await requestBtn.waitFor({ state: "visible" });
await requestBtn.click();
await expect(page).toHaveURL(/\/developer-requests$/);
// Fill Form (using direct selectors for reliability)
await page.locator("#org").fill("QA Team");
const openRequestBtn = page.getByRole("button", {
name: /신규 신청하기|Request|Apply/,
});
await openRequestBtn.click();
// Fill Form (organization is read-only and comes from the active tenant)
await page.locator("#reason").fill("Need to test OIDC integration");
// Submit
await page.getByRole('button', { name: /신청하기|Submit/ }).click();
await page.getByRole("button", { name: "신청하기", exact: true }).click();
// Verify Status - Look for "Pending" or "대기" anywhere
await expect(page.locator("body")).toContainText(/대기|Pending/);
});
test("super admin can approve, reject and cancel developer requests", async ({ page }) => {
test("super admin can approve, reject and cancel developer requests", async ({
page,
}) => {
const request: DeveloperRequest = {
id: "req-admin-test",
userId: "user-1",
userName: "Requester User",
name: "Requester User",
name: "Requester User",
userEmail: "user1@example.com",
organization: "Dev Team",
reason: "API Test",
@@ -72,26 +83,30 @@ test.describe("DevFront developer request and management", () => {
await page.goto("/developer-requests");
// Wait for data to load
await page.waitForLoadState('networkidle');
await expect(page.locator("table")).toContainText("Requester User", { timeout: 10000 });
await page.waitForLoadState("networkidle");
await expect(page.locator("table")).toContainText("Requester User", {
timeout: 10000,
});
// Approve
const approveBtn = page.getByRole('button', { name: '승인' }).first();
const approveBtn = page.getByRole("button", { name: "승인" }).first();
await approveBtn.click();
await expect(page.locator("table")).toContainText(/승인됨|Approved/);
// Cancel approval (Requires notes)
await page.locator("input.h-8").first().fill("Cancellation reason");
await page.getByRole('button', { name: '승인 취소' }).click();
await page.getByRole("button", { name: "승인 취소" }).click();
await expect(page.locator("table")).toContainText(/대기|Pending/);
// Reject (Requires notes)
await page.locator("input.h-8").first().fill("Rejection reason");
await page.getByRole('button', { name: '반려' }).click();
await page.getByRole("button", { name: "반려" }).click();
await expect(page.locator("table")).toContainText(/반려됨|Rejected/);
});
test("approved user can see 'Add App' guidance and create RP", async ({ page }) => {
test("approved user can see 'Add App' guidance and create RP", async ({
page,
}) => {
const request: DeveloperRequest = {
id: "req-approved",
userId: "playwright-user",
@@ -112,33 +127,41 @@ test.describe("DevFront developer request and management", () => {
developerRequests: [request],
};
await seedAuth(page, "rp_admin");
await seedAuth(page, "rp_admin");
await installDevApiMock(page, state);
await page.goto("/clients");
// Click Add App
const createBtn = page.getByRole('button', { name: /연동 앱 추가/ }).first();
const createBtn = page
.getByRole("button", { name: /연동 앱 추가/ })
.first();
await createBtn.click();
// Fill Form (Must fill all mandatory fields to enable Submit)
await expect(page).toHaveURL(/\/clients\/new$/);
const nameInput = page.locator("input[placeholder*='Awesome']");
const nameInput = page.getByPlaceholder(
/My Awesome Application|예: 멋진 애플리케이션/,
);
await nameInput.fill("E2E Test RP");
await nameInput.press('Tab');
await nameInput.press("Tab");
const uriInput = page.locator("textarea.font-mono");
await uriInput.fill("https://example.com/callback");
await uriInput.press('Tab');
await uriInput.press("Tab");
// Submit
const submitBtn = page.getByRole('button', { name: /생성/ }).filter({ hasNotText: '취소' });
const submitBtn = page
.getByRole("button", { name: /생성/ })
.filter({ hasNotText: "취소" });
await expect(submitBtn).toBeEnabled({ timeout: 10000 });
await submitBtn.click();
// Verification
await expect(page).toHaveURL(/\/clients\/client-\d+\/settings$/);
await expect(page.locator("h1")).toContainText(/설정|Settings/);
await expect(
page.getByRole("heading", { name: /연동 앱 설정|Settings/ }),
).toBeVisible();
});
});

View File

@@ -261,19 +261,30 @@ export async function installDevApiMock(page: Page, state: DevApiMockState) {
const { pathname, searchParams } = url;
const method = request.method();
if (pathname === "/api/v1/dev/requests" && method === "GET") {
return json(route, { items: state.developerRequests ?? [] });
if (
(pathname === "/api/v1/dev/requests" ||
pathname === "/api/v1/dev/developer-request/list") &&
method === "GET"
) {
return json(route, state.developerRequests ?? []);
}
if (pathname === "/api/v1/dev/requests" && method === "POST") {
const payload = (request.postDataJSON() as {
organization?: string;
reason?: string;
}) || {};
if (
(pathname === "/api/v1/dev/requests" ||
pathname === "/api/v1/dev/developer-request") &&
method === "POST"
) {
const payload =
(request.postDataJSON() as {
name?: string;
organization?: string;
reason?: string;
}) || {};
const created: DeveloperRequest = {
id: `req-${Date.now()}`,
userId: "playwright-user",
userName: "Playwright User",
userName: payload.name ?? "Playwright User",
name: payload.name ?? "Playwright User",
userEmail: "playwright@example.com",
organization: payload.organization ?? "Unknown",
reason: payload.reason ?? "No reason",
@@ -288,7 +299,11 @@ export async function installDevApiMock(page: Page, state: DevApiMockState) {
return json(route, created, 201);
}
if (pathname === "/api/v1/dev/requests/status" && method === "GET") {
if (
(pathname === "/api/v1/dev/requests/status" ||
pathname === "/api/v1/dev/developer-request/status") &&
method === "GET"
) {
const myRequest = (state.developerRequests ?? []).find(
(r) => r.userId === "playwright-user",
);
@@ -296,11 +311,12 @@ export async function installDevApiMock(page: Page, state: DevApiMockState) {
}
if (
pathname.startsWith("/api/v1/dev/requests/") &&
(pathname.startsWith("/api/v1/dev/requests/") ||
pathname.startsWith("/api/v1/dev/developer-request/")) &&
pathname.endsWith("/approve") &&
method === "POST"
) {
const reqId = pathname.split("/")[5] ?? "";
const reqId = pathname.split("/")[5] ?? pathname.split("/")[4] ?? "";
const found = state.developerRequests?.find((r) => r.id === reqId);
if (!found) return json(route, { error: "not found" }, 404);
found.status = "approved";
@@ -309,11 +325,12 @@ export async function installDevApiMock(page: Page, state: DevApiMockState) {
}
if (
pathname.startsWith("/api/v1/dev/requests/") &&
(pathname.startsWith("/api/v1/dev/requests/") ||
pathname.startsWith("/api/v1/dev/developer-request/")) &&
pathname.endsWith("/reject") &&
method === "POST"
) {
const reqId = pathname.split("/")[5] ?? "";
const reqId = pathname.split("/")[5] ?? pathname.split("/")[4] ?? "";
const found = state.developerRequests?.find((r) => r.id === reqId);
if (!found) return json(route, { error: "not found" }, 404);
found.status = "rejected";
@@ -322,11 +339,12 @@ export async function installDevApiMock(page: Page, state: DevApiMockState) {
}
if (
pathname.startsWith("/api/v1/dev/requests/") &&
pathname.endsWith("/cancel") &&
(pathname.startsWith("/api/v1/dev/requests/") ||
pathname.startsWith("/api/v1/dev/developer-request/")) &&
(pathname.endsWith("/cancel") || pathname.endsWith("/cancel-approval")) &&
method === "POST"
) {
const reqId = pathname.split("/")[5] ?? "";
const reqId = pathname.split("/")[5] ?? pathname.split("/")[4] ?? "";
const found = state.developerRequests?.find((r) => r.id === reqId);
if (!found) return json(route, { error: "not found" }, 404);
found.status = "pending";