forked from baron/baron-sso
devfront 로그인 claim e2e 검증 추가
This commit is contained in:
238
devfront/tests/devfront-login-claims.spec.ts
Normal file
238
devfront/tests/devfront-login-claims.spec.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import {
|
||||
getPersistedOidcUser,
|
||||
installDevApiMock,
|
||||
seedAuth,
|
||||
} from "./helpers/devfront-fixtures";
|
||||
import { captureEvidence } from "./helpers/evidence";
|
||||
|
||||
type ClaimScenario = {
|
||||
title: string;
|
||||
role: "super_admin" | "user";
|
||||
tenantName: string;
|
||||
userMeTenantId: string;
|
||||
userMeCompanyCode: string;
|
||||
profileClaims: Record<string, unknown>;
|
||||
expectedProfileAssertions: Record<string, unknown>;
|
||||
expectTenantsToBeAbsent?: boolean;
|
||||
};
|
||||
|
||||
const claimScenarios: ClaimScenario[] = [
|
||||
{
|
||||
title: "Server Side App preserves tenant and rp claims",
|
||||
role: "super_admin",
|
||||
tenantName: "Server Side Tenant",
|
||||
userMeTenantId: "tenant-server",
|
||||
userMeCompanyCode: "server-hq",
|
||||
profileClaims: {
|
||||
tenant_id: "tenant-server",
|
||||
companyCode: "server-hq",
|
||||
profile: {
|
||||
names: {
|
||||
name: "서버 앱 사용자",
|
||||
},
|
||||
emails: ["server@example.com"],
|
||||
},
|
||||
joined_tenants: ["tenant-server", "tenant-ops"],
|
||||
tenants: {
|
||||
"tenant-server": {
|
||||
department: "Platform",
|
||||
grade: "Lead",
|
||||
},
|
||||
"tenant-ops": {
|
||||
department: "Operations",
|
||||
grade: "Member",
|
||||
},
|
||||
},
|
||||
rp_claims: {
|
||||
approvalLevel: "A",
|
||||
},
|
||||
metadata: {
|
||||
rp_custom_claims: {
|
||||
"server-app": {
|
||||
approvalLevel: "A",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedProfileAssertions: {
|
||||
tenant_id: "tenant-server",
|
||||
companyCode: "server-hq",
|
||||
joined_tenants: ["tenant-server", "tenant-ops"],
|
||||
rp_claims: {
|
||||
approvalLevel: "A",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "PKCE preserves nested profile claims without tenant map expansion",
|
||||
role: "user",
|
||||
tenantName: "PKCE Tenant",
|
||||
userMeTenantId: "tenant-pkce",
|
||||
userMeCompanyCode: "pkce-hq",
|
||||
profileClaims: {
|
||||
tenant_id: "tenant-pkce",
|
||||
companyCode: "pkce-hq",
|
||||
profile: {
|
||||
names: {
|
||||
name: "PKCE 사용자",
|
||||
},
|
||||
emails: ["pkce@example.com"],
|
||||
},
|
||||
joined_tenants: ["tenant-pkce"],
|
||||
rp_claims: {
|
||||
features: ["sso", "claims"],
|
||||
},
|
||||
metadata: {
|
||||
rp_custom_claims: {
|
||||
"pkce-app": {
|
||||
features: ["sso", "claims"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedProfileAssertions: {
|
||||
tenant_id: "tenant-pkce",
|
||||
companyCode: "pkce-hq",
|
||||
joined_tenants: ["tenant-pkce"],
|
||||
rp_claims: {
|
||||
features: ["sso", "claims"],
|
||||
},
|
||||
},
|
||||
expectTenantsToBeAbsent: true,
|
||||
},
|
||||
{
|
||||
title: "Headless login keeps session claims together with rp claims",
|
||||
role: "super_admin",
|
||||
tenantName: "Headless Tenant",
|
||||
userMeTenantId: "tenant-headless",
|
||||
userMeCompanyCode: "headless-hq",
|
||||
profileClaims: {
|
||||
tenant_id: "tenant-headless",
|
||||
companyCode: "headless-hq",
|
||||
profile: {
|
||||
names: {
|
||||
name: "헤드리스 사용자",
|
||||
},
|
||||
emails: ["headless@example.com"],
|
||||
},
|
||||
joined_tenants: ["tenant-headless", "tenant-support"],
|
||||
tenants: {
|
||||
"tenant-headless": {
|
||||
department: "Automation",
|
||||
grade: "Manager",
|
||||
},
|
||||
"tenant-support": {
|
||||
department: "Support",
|
||||
grade: "Agent",
|
||||
},
|
||||
},
|
||||
rp_claims: {
|
||||
approvalLevel: "B",
|
||||
loginMode: "headless",
|
||||
},
|
||||
sid: "session-headless-1",
|
||||
session_id: "session-headless-1",
|
||||
metadata: {
|
||||
rp_custom_claims: {
|
||||
"headless-app": {
|
||||
approvalLevel: "B",
|
||||
loginMode: "headless",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedProfileAssertions: {
|
||||
tenant_id: "tenant-headless",
|
||||
companyCode: "headless-hq",
|
||||
joined_tenants: ["tenant-headless", "tenant-support"],
|
||||
rp_claims: {
|
||||
approvalLevel: "B",
|
||||
loginMode: "headless",
|
||||
},
|
||||
sid: "session-headless-1",
|
||||
session_id: "session-headless-1",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
test.describe("DevFront login claims", () => {
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
if (testInfo.status === "passed") {
|
||||
await captureEvidence(page, testInfo, testInfo.title);
|
||||
}
|
||||
});
|
||||
|
||||
for (const scenario of claimScenarios) {
|
||||
test(scenario.title, async ({ page }) => {
|
||||
await seedAuth(page, {
|
||||
role: scenario.role,
|
||||
profile: scenario.profileClaims,
|
||||
});
|
||||
|
||||
await installDevApiMock(page, {
|
||||
clients: [],
|
||||
consents: [],
|
||||
auditLogsByCursor: undefined,
|
||||
users: [],
|
||||
tenants: [
|
||||
{
|
||||
id: scenario.userMeTenantId,
|
||||
name: scenario.tenantName,
|
||||
slug: scenario.userMeCompanyCode,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await page.route("**/api/v1/user/me", async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
id: "playwright-user",
|
||||
loginId: "playwright@example.com",
|
||||
email: "playwright@example.com",
|
||||
name: "Playwright User",
|
||||
phoneNumber: "",
|
||||
department: "QA",
|
||||
tenantId: "",
|
||||
tenantName: "",
|
||||
role: scenario.role,
|
||||
createdAt: "2026-06-01T00:00:00.000Z",
|
||||
updatedAt: "2026-06-01T00:00:00.000Z",
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto("/profile");
|
||||
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "내 정보" }),
|
||||
).toBeVisible();
|
||||
const storedUser = await getPersistedOidcUser(page);
|
||||
expect(storedUser).not.toBeNull();
|
||||
expect(storedUser?.profile).toMatchObject(
|
||||
scenario.expectedProfileAssertions,
|
||||
);
|
||||
if (scenario.expectTenantsToBeAbsent) {
|
||||
expect(storedUser?.profile).not.toHaveProperty("tenants");
|
||||
} else {
|
||||
expect(storedUser?.profile).toHaveProperty("tenants");
|
||||
}
|
||||
await expect(
|
||||
page.getByText(String(scenario.profileClaims.tenant_id)),
|
||||
).toBeVisible();
|
||||
await expect(page.getByText(scenario.userMeCompanyCode)).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "시스템 역할" }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(
|
||||
scenario.role === "super_admin"
|
||||
? /시스템 관리자|Super Admin/i
|
||||
: /일반 사용자|General User/i,
|
||||
),
|
||||
).toBeVisible();
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user