forked from baron/baron-sso
custom claim 타입보정 UI. 대표테넌트 노출 보정
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import {
|
||||
type ClientRelation,
|
||||
type Consent,
|
||||
installDevApiMock,
|
||||
makeClient,
|
||||
@@ -7,6 +8,39 @@ import {
|
||||
} from "./helpers/devfront-fixtures";
|
||||
import { installDevFrontStaticRoutes } from "./helpers/static-devfront";
|
||||
|
||||
const editRelations = [
|
||||
{
|
||||
relation: "config_editor",
|
||||
subject: "User:playwright-user",
|
||||
subjectType: "User",
|
||||
subjectId: "playwright-user",
|
||||
},
|
||||
{
|
||||
relation: "admins",
|
||||
subject: "User:playwright-user",
|
||||
subjectType: "User",
|
||||
subjectId: "playwright-user",
|
||||
},
|
||||
{
|
||||
relation: "config_editor",
|
||||
subject: "User:admin-user",
|
||||
subjectType: "User",
|
||||
subjectId: "admin-user",
|
||||
},
|
||||
{
|
||||
relation: "config_editor",
|
||||
subject: "User:undefined",
|
||||
subjectType: "User",
|
||||
subjectId: "undefined",
|
||||
},
|
||||
{
|
||||
relation: "config_editor",
|
||||
subject: "User:",
|
||||
subjectType: "User",
|
||||
subjectId: "",
|
||||
},
|
||||
] satisfies ClientRelation[];
|
||||
|
||||
test.describe("DevFront RP claim cache", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await installDevFrontStaticRoutes(page);
|
||||
@@ -33,6 +67,9 @@ test.describe("DevFront RP claim cache", () => {
|
||||
}),
|
||||
],
|
||||
consents: [] as Consent[],
|
||||
relations: {
|
||||
"client-claims": editRelations,
|
||||
},
|
||||
auditLogsByCursor: undefined,
|
||||
mockRole: "super_admin",
|
||||
};
|
||||
@@ -44,6 +81,7 @@ test.describe("DevFront RP claim cache", () => {
|
||||
.getByPlaceholder(/e\.g\. locale|예: locale/i)
|
||||
.first();
|
||||
await expect(claimKeyInput).toHaveValue("old_claim");
|
||||
await expect(claimKeyInput).toBeEnabled();
|
||||
|
||||
await claimKeyInput.fill("new_claim");
|
||||
await page.getByRole("button", { name: /^저장$|^Save$/i }).click();
|
||||
@@ -60,4 +98,208 @@ test.describe("DevFront RP claim cache", () => {
|
||||
.toBe("new_claim");
|
||||
await expect(claimKeyInput).toHaveValue("new_claim");
|
||||
});
|
||||
|
||||
test("forces read permission on when write permission is enabled", async ({
|
||||
page,
|
||||
}) => {
|
||||
const state = {
|
||||
clients: [
|
||||
makeClient("client-claims", {
|
||||
name: "Claims app",
|
||||
metadata: {
|
||||
id_token_claims: [
|
||||
{
|
||||
namespace: "rp_claims",
|
||||
key: "locale",
|
||||
value: "ko",
|
||||
valueType: "text",
|
||||
readPermission: "admin_only",
|
||||
writePermission: "admin_only",
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
consents: [] as Consent[],
|
||||
relations: {
|
||||
"client-claims": editRelations,
|
||||
},
|
||||
auditLogsByCursor: undefined,
|
||||
mockRole: "super_admin",
|
||||
};
|
||||
await installDevApiMock(page, state);
|
||||
|
||||
await page.goto("http://devfront.test/clients/client-claims/settings");
|
||||
|
||||
const readSwitch = page
|
||||
.getByRole("switch", { name: /사용자 읽기|Allow user read/i })
|
||||
.first();
|
||||
const writeSwitch = page
|
||||
.getByRole("switch", { name: /사용자 쓰기|Allow user write/i })
|
||||
.first();
|
||||
|
||||
await expect(readSwitch).toHaveAttribute("aria-checked", "false");
|
||||
await expect(writeSwitch).toHaveAttribute("aria-checked", "false");
|
||||
await expect(readSwitch).toBeEnabled();
|
||||
await expect(writeSwitch).toBeEnabled();
|
||||
|
||||
await writeSwitch.click();
|
||||
|
||||
await expect(readSwitch).toHaveAttribute("aria-checked", "true");
|
||||
await expect(writeSwitch).toHaveAttribute("aria-checked", "true");
|
||||
|
||||
await page.getByRole("button", { name: /^저장$|^Save$/i }).click();
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
(
|
||||
state.clients[0]?.metadata?.id_token_claims as
|
||||
| Array<{
|
||||
readPermission?: string;
|
||||
writePermission?: string;
|
||||
}>
|
||||
| undefined
|
||||
)?.[0],
|
||||
)
|
||||
.toMatchObject({
|
||||
readPermission: "user_and_admin",
|
||||
writePermission: "user_and_admin",
|
||||
});
|
||||
});
|
||||
|
||||
test("blocks saving an RP claim default value that does not match the selected value type", async ({
|
||||
page,
|
||||
}) => {
|
||||
const state = {
|
||||
clients: [
|
||||
makeClient("client-claims", {
|
||||
name: "Claims app",
|
||||
metadata: {
|
||||
id_token_claims: [
|
||||
{
|
||||
namespace: "rp_claims",
|
||||
key: "profile",
|
||||
value: "{}",
|
||||
valueType: "text",
|
||||
readPermission: "admin_only",
|
||||
writePermission: "admin_only",
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
consents: [] as Consent[],
|
||||
relations: {
|
||||
"client-claims": editRelations,
|
||||
},
|
||||
auditLogsByCursor: undefined,
|
||||
mockRole: "super_admin",
|
||||
};
|
||||
await installDevApiMock(page, state);
|
||||
|
||||
await page.goto("http://devfront.test/clients/client-claims/settings");
|
||||
|
||||
await page
|
||||
.getByLabel(/Claim 값 타입|Claim value type/i)
|
||||
.first()
|
||||
.selectOption("object");
|
||||
await page
|
||||
.locator('textarea[placeholder="{\\"key\\": \\"value\\"}"]')
|
||||
.fill("not-json");
|
||||
|
||||
await expect(
|
||||
page.getByRole("button", { name: /^저장$|^Save$/i }),
|
||||
).toBeDisabled();
|
||||
|
||||
expect(
|
||||
(
|
||||
state.clients[0]?.metadata?.id_token_claims as
|
||||
| Array<{ valueType?: string; value?: string }>
|
||||
| undefined
|
||||
)?.[0],
|
||||
).toMatchObject({
|
||||
value: "{}",
|
||||
valueType: "text",
|
||||
});
|
||||
});
|
||||
|
||||
test("saves a float RP claim default value and blocks decimal values for integer number claims", async ({
|
||||
page,
|
||||
}) => {
|
||||
const state = {
|
||||
clients: [
|
||||
makeClient("client-claims", {
|
||||
name: "Claims app",
|
||||
metadata: {
|
||||
id_token_claims: [
|
||||
{
|
||||
namespace: "rp_claims",
|
||||
key: "ratio",
|
||||
value: "0",
|
||||
valueType: "text",
|
||||
readPermission: "admin_only",
|
||||
writePermission: "admin_only",
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
consents: [] as Consent[],
|
||||
relations: {
|
||||
"client-claims": editRelations,
|
||||
},
|
||||
auditLogsByCursor: undefined,
|
||||
mockRole: "super_admin",
|
||||
};
|
||||
await installDevApiMock(page, state);
|
||||
|
||||
await page.goto("http://devfront.test/clients/client-claims/settings");
|
||||
|
||||
await page
|
||||
.getByLabel(/Claim 값 타입|Claim value type/i)
|
||||
.first()
|
||||
.selectOption("float");
|
||||
await page
|
||||
.getByPlaceholder(/기본값을 입력하세요|Enter the default value/i)
|
||||
.first()
|
||||
.fill("3.14");
|
||||
await page.getByRole("button", { name: /^저장$|^Save$/i }).click();
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
(
|
||||
state.clients[0]?.metadata?.id_token_claims as
|
||||
| Array<{ valueType?: string; value?: string }>
|
||||
| undefined
|
||||
)?.[0],
|
||||
)
|
||||
.toMatchObject({
|
||||
value: "3.14",
|
||||
valueType: "float",
|
||||
});
|
||||
|
||||
const valueTypeSelect = page
|
||||
.getByLabel(/Claim 값 타입|Claim value type/i)
|
||||
.first();
|
||||
await expect(valueTypeSelect).toHaveValue("float");
|
||||
await expect(
|
||||
page.getByRole("button", { name: /^저장$|^Save$/i }),
|
||||
).toBeEnabled();
|
||||
|
||||
await valueTypeSelect.selectOption("number");
|
||||
await expect(valueTypeSelect).toHaveValue("number");
|
||||
await page
|
||||
.getByPlaceholder(/기본값을 입력하세요|Enter the default value/i)
|
||||
.first()
|
||||
.fill("3.14");
|
||||
|
||||
await expect(
|
||||
page.getByText(/Claim 기본값이 타입과 맞지 않습니다|does not match/i),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("button", { name: /^저장$|^Save$/i }),
|
||||
).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
makeClient,
|
||||
seedAuth,
|
||||
} from "./helpers/devfront-fixtures";
|
||||
import { installDevFrontStaticRoutes } from "./helpers/static-devfront";
|
||||
|
||||
function expectClientTabsOrder(pagePath: string, expectedActive: RegExp) {
|
||||
return async ({ page }: { page: Page }) => {
|
||||
@@ -24,9 +25,10 @@ function expectClientTabsOrder(pagePath: string, expectedActive: RegExp) {
|
||||
},
|
||||
auditLogsByCursor: undefined,
|
||||
};
|
||||
await installDevFrontStaticRoutes(page);
|
||||
await installDevApiMock(page, state);
|
||||
|
||||
await page.goto(pagePath);
|
||||
await page.goto(`http://devfront.test${pagePath}`);
|
||||
|
||||
const header = page
|
||||
.locator("header")
|
||||
@@ -38,7 +40,7 @@ function expectClientTabsOrder(pagePath: string, expectedActive: RegExp) {
|
||||
|
||||
await expect(tabs).toHaveText([
|
||||
"연동 설정",
|
||||
"사용자 Claim",
|
||||
"동의 및 Claims",
|
||||
"설정",
|
||||
"관계",
|
||||
]);
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
seedAuth,
|
||||
} from "./helpers/devfront-fixtures";
|
||||
import { captureEvidence } from "./helpers/evidence";
|
||||
import { installDevFrontStaticRoutes } from "./helpers/static-devfront";
|
||||
|
||||
test.describe("DevFront consents", () => {
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
@@ -15,6 +16,7 @@ test.describe("DevFront consents", () => {
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await installDevFrontStaticRoutes(page);
|
||||
page.on("dialog", async (dialog) => {
|
||||
await dialog.accept();
|
||||
});
|
||||
@@ -81,7 +83,7 @@ test.describe("DevFront consents", () => {
|
||||
};
|
||||
await installDevApiMock(page, state);
|
||||
|
||||
await page.goto("/clients/client-consent/consents");
|
||||
await page.goto("http://devfront.test/clients/client-consent/consents");
|
||||
await expect(page.getByText("Alice")).toBeVisible();
|
||||
await expect(page.getByText("Tenant A")).toBeVisible();
|
||||
await expect(page.getByText(/approvalLevel:\s*A/)).toBeVisible();
|
||||
@@ -127,4 +129,43 @@ test.describe("DevFront consents", () => {
|
||||
await page.getByRole("button", { name: /권한 철회|철회|Revoke/i }).click();
|
||||
await expect(page.getByText(/Revoked|철회/i).first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("does not allow adding undefined RP claims from consents and claims", async ({
|
||||
page,
|
||||
}) => {
|
||||
const state = {
|
||||
clients: [
|
||||
makeClient("client-consent", {
|
||||
name: "Consent app",
|
||||
metadata: {},
|
||||
}),
|
||||
],
|
||||
consents: [
|
||||
{
|
||||
subject: "user-1",
|
||||
userName: "Alice",
|
||||
clientId: "client-consent",
|
||||
clientName: "Consent app",
|
||||
grantedScopes: ["openid", "profile"],
|
||||
authenticatedAt: "2026-03-03T08:00:00.000Z",
|
||||
createdAt: "2026-03-02T08:00:00.000Z",
|
||||
status: "active",
|
||||
tenantId: "tenant-a",
|
||||
tenantName: "Tenant A",
|
||||
rpMetadata: {},
|
||||
},
|
||||
] as Consent[],
|
||||
auditLogsByCursor: undefined,
|
||||
};
|
||||
await installDevApiMock(page, state);
|
||||
|
||||
await page.goto("http://devfront.test/clients/client-consent/consents");
|
||||
await page.getByRole("button", { name: /Claims|Claim/i }).click();
|
||||
|
||||
await expect(page.getByText("RP Custom Claims")).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("button", { name: /^추가$|^Add$/ }),
|
||||
).toHaveCount(0);
|
||||
await expect(page.getByPlaceholder(/claim_key/i)).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user