forked from baron/baron-sso
75f192fb24 기준 병합 code-check 수정
This commit is contained in:
@@ -158,7 +158,9 @@ describe("AuditLogsPage", () => {
|
||||
};
|
||||
|
||||
const container = await renderPage();
|
||||
expect(container.textContent).toContain("감사 로그는 개발자 권한이 있어야 볼 수 있습니다.");
|
||||
expect(container.textContent).toContain(
|
||||
"감사 로그는 개발자 권한이 있어야 볼 수 있습니다.",
|
||||
);
|
||||
|
||||
const button = Array.from(container.querySelectorAll("button")).find(
|
||||
(item) => item.textContent?.includes("개발자 권한 신청"),
|
||||
@@ -177,7 +179,9 @@ describe("AuditLogsPage", () => {
|
||||
.spyOn(URL, "createObjectURL")
|
||||
.mockReturnValue("blob:csv");
|
||||
const revokeObjectURL = vi.spyOn(URL, "revokeObjectURL").mockReturnValue();
|
||||
const clickSpy = vi.spyOn(HTMLAnchorElement.prototype, "click").mockImplementation(() => {});
|
||||
const clickSpy = vi
|
||||
.spyOn(HTMLAnchorElement.prototype, "click")
|
||||
.mockImplementation(() => {});
|
||||
|
||||
const container = await renderPage();
|
||||
expect(container.textContent).toContain("table:1");
|
||||
|
||||
@@ -31,9 +31,10 @@ vi.mock("react-oidc-context", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("react-router-dom", async () => {
|
||||
const actual = await vi.importActual<typeof import("react-router-dom")>(
|
||||
"react-router-dom",
|
||||
);
|
||||
const actual =
|
||||
await vi.importActual<typeof import("react-router-dom")>(
|
||||
"react-router-dom",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
useNavigate: () => navigateMock,
|
||||
@@ -175,7 +176,9 @@ describe("ClientsPage", () => {
|
||||
});
|
||||
|
||||
const container = await renderPage();
|
||||
expect(container.textContent).toContain("총 6개의 애플리케이션이 등록되어 있습니다.");
|
||||
expect(container.textContent).toContain(
|
||||
"총 6개의 애플리케이션이 등록되어 있습니다.",
|
||||
);
|
||||
expect(container.textContent).toContain("App 6");
|
||||
expect(container.textContent).toContain("App 2");
|
||||
expect(container.textContent).not.toContain("App 1");
|
||||
@@ -192,26 +195,27 @@ describe("ClientsPage", () => {
|
||||
expect(container.textContent).toContain("App 6");
|
||||
expect(container.textContent).toContain("접기");
|
||||
|
||||
const advancedButton = Array.from(container.querySelectorAll("button")).find(
|
||||
(button) => button.textContent === "Advanced Filters",
|
||||
);
|
||||
const advancedButton = Array.from(
|
||||
container.querySelectorAll("button"),
|
||||
).find((button) => button.textContent === "Advanced Filters");
|
||||
expect(advancedButton).toBeTruthy();
|
||||
|
||||
await act(async () => {
|
||||
advancedButton?.dispatchEvent(
|
||||
new MouseEvent("click", { bubbles: true }),
|
||||
);
|
||||
advancedButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
});
|
||||
|
||||
const searchInput = Array.from(
|
||||
container.querySelectorAll("input"),
|
||||
).find((input) =>
|
||||
input.getAttribute("placeholder")?.includes("클라이언트 이름/ID로 검색"),
|
||||
const searchInput = Array.from(container.querySelectorAll("input")).find(
|
||||
(input) =>
|
||||
input
|
||||
.getAttribute("placeholder")
|
||||
?.includes("클라이언트 이름/ID로 검색"),
|
||||
) as HTMLInputElement | undefined;
|
||||
expect(searchInput).toBeTruthy();
|
||||
if (!searchInput) {
|
||||
throw new Error("Expected search input to be rendered");
|
||||
}
|
||||
|
||||
await act(async () => {
|
||||
await setInputValue(searchInput!, "missing-client");
|
||||
await setInputValue(searchInput, "missing-client");
|
||||
});
|
||||
|
||||
expect(container.textContent).toContain("조건에 맞는 연동 앱이 없습니다.");
|
||||
@@ -226,7 +230,7 @@ describe("ClientsPage", () => {
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await setInputValue(searchInput!, "");
|
||||
await setInputValue(searchInput, "");
|
||||
});
|
||||
|
||||
expect(container.textContent).toContain("App 1");
|
||||
|
||||
@@ -532,10 +532,12 @@ function ClientsPage() {
|
||||
t("ui.dev.clients.untitled", "Untitled")}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t(
|
||||
"ui.dev.clients.tenant_scoped",
|
||||
"Tenant-scoped",
|
||||
)}
|
||||
<span aria-hidden="true">
|
||||
{t(
|
||||
"ui.dev.clients.tenant_scoped",
|
||||
"Tenant-scoped",
|
||||
)}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
@@ -615,14 +617,9 @@ function ClientsPage() {
|
||||
"ui.dev.clients.list.collapse_aria",
|
||||
"연동 앱 목록 접기",
|
||||
)
|
||||
: t(
|
||||
"ui.dev.clients.list.more_aria",
|
||||
"연동 앱 목록 더보기",
|
||||
)
|
||||
}
|
||||
onClick={() =>
|
||||
setIsClientListExpanded((current) => !current)
|
||||
: t("ui.dev.clients.list.more_aria", "연동 앱 목록 더보기")
|
||||
}
|
||||
onClick={() => setIsClientListExpanded((current) => !current)}
|
||||
>
|
||||
{isClientListExpanded
|
||||
? t("ui.common.collapse", "접기")
|
||||
|
||||
@@ -8,7 +8,7 @@ vi.mock("../../../components/ui/avatar", () => ({
|
||||
Avatar: ({ children }: { children: ReactNode }) => (
|
||||
<div data-testid="avatar">{children}</div>
|
||||
),
|
||||
AvatarImage: (props: ComponentProps<"img">) => <img {...props} />,
|
||||
AvatarImage: (props: ComponentProps<"img">) => <img alt="" {...props} />,
|
||||
AvatarFallback: ({ children }: { children: ReactNode }) => (
|
||||
<div data-testid="fallback">{children}</div>
|
||||
),
|
||||
|
||||
@@ -9,9 +9,10 @@ const listIdpConfigsMock = vi.fn();
|
||||
const createIdpConfigMock = vi.fn();
|
||||
|
||||
vi.mock("react-router-dom", async () => {
|
||||
const actual = await vi.importActual<typeof import("react-router-dom")>(
|
||||
"react-router-dom",
|
||||
);
|
||||
const actual =
|
||||
await vi.importActual<typeof import("react-router-dom")>(
|
||||
"react-router-dom",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
useParams: () => params,
|
||||
@@ -19,10 +20,8 @@ vi.mock("react-router-dom", async () => {
|
||||
});
|
||||
|
||||
vi.mock("../../../lib/devApi", () => ({
|
||||
listIdpConfigsForClient: (clientId: string) =>
|
||||
listIdpConfigsMock(clientId),
|
||||
createIdpConfigForClient: (payload: unknown) =>
|
||||
createIdpConfigMock(payload),
|
||||
listIdpConfigsForClient: (clientId: string) => listIdpConfigsMock(clientId),
|
||||
createIdpConfigForClient: (payload: unknown) => createIdpConfigMock(payload),
|
||||
}));
|
||||
|
||||
vi.mock("../../../lib/i18n", () => ({
|
||||
@@ -146,16 +145,15 @@ describe("ClientFederationPage", () => {
|
||||
'input[name="oidc_client_secret"]',
|
||||
) as HTMLInputElement | null;
|
||||
|
||||
expect(displayName).toBeTruthy();
|
||||
expect(issuerUrl).toBeTruthy();
|
||||
expect(clientId).toBeTruthy();
|
||||
expect(clientSecret).toBeTruthy();
|
||||
if (!displayName || !issuerUrl || !clientId || !clientSecret) {
|
||||
throw new Error("Expected federation form inputs to be rendered");
|
||||
}
|
||||
|
||||
await act(async () => {
|
||||
await setInputValue(displayName!, "New Provider");
|
||||
await setInputValue(issuerUrl!, "https://login.example");
|
||||
await setInputValue(clientId!, "client-oidc");
|
||||
await setInputValue(clientSecret!, "secret-value");
|
||||
await setInputValue(displayName, "New Provider");
|
||||
await setInputValue(issuerUrl, "https://login.example");
|
||||
await setInputValue(clientId, "client-oidc");
|
||||
await setInputValue(clientSecret, "secret-value");
|
||||
});
|
||||
|
||||
const submitButton = Array.from(container.querySelectorAll("button")).find(
|
||||
|
||||
@@ -159,10 +159,12 @@ describe("DeveloperRequestPage", () => {
|
||||
const reasonField = container.querySelector(
|
||||
"textarea",
|
||||
) as HTMLTextAreaElement | null;
|
||||
expect(reasonField).toBeTruthy();
|
||||
if (!reasonField) {
|
||||
throw new Error("Expected reason textarea to be rendered");
|
||||
}
|
||||
|
||||
await act(async () => {
|
||||
await setTextAreaValue(reasonField!, "Need RP access");
|
||||
await setTextAreaValue(reasonField, "Need RP access");
|
||||
});
|
||||
|
||||
const submitButton = Array.from(container.querySelectorAll("button")).find(
|
||||
|
||||
@@ -119,9 +119,7 @@ function resolveAppLocale(): AppLocale {
|
||||
return pathLocale;
|
||||
}
|
||||
|
||||
return window.navigator.language.toLowerCase().startsWith("ko")
|
||||
? "ko"
|
||||
: "en";
|
||||
return window.navigator.language.toLowerCase().startsWith("ko") ? "ko" : "en";
|
||||
}
|
||||
|
||||
function formatRecentChangeTimestamp(value: string) {
|
||||
@@ -390,7 +388,10 @@ function summarizeRecentChanges(
|
||||
items: RecentClientChange[],
|
||||
period: RPUsagePeriod,
|
||||
): RecentChangePoint[] {
|
||||
const byDate = new Map<string, { changeCount: number; actors: Set<string> }>();
|
||||
const byDate = new Map<
|
||||
string,
|
||||
{ changeCount: number; actors: Set<string> }
|
||||
>();
|
||||
for (const item of items) {
|
||||
const bucket = toPeriodBucket(item.timestamp.slice(0, 10), period);
|
||||
const current = byDate.get(bucket) ?? {
|
||||
@@ -447,7 +448,9 @@ function buildRecentChangeSeries(
|
||||
items: RecentClientChange[],
|
||||
period: RPUsagePeriod,
|
||||
): RecentChangeSeries[] {
|
||||
const dates = summarizeRecentChanges(items, period).map((point) => point.date);
|
||||
const dates = summarizeRecentChanges(items, period).map(
|
||||
(point) => point.date,
|
||||
);
|
||||
const byClient = new Map<
|
||||
string,
|
||||
{
|
||||
@@ -937,7 +940,7 @@ function GlobalOverviewPage() {
|
||||
const [visibleRecentClientChangesCount, setVisibleRecentClientChangesCount] =
|
||||
useState(6);
|
||||
const [isRecentChangesDetailOpen, setIsRecentChangesDetailOpen] =
|
||||
useState(false);
|
||||
useState(true);
|
||||
const usageDays = period === "day" ? 14 : period === "week" ? 84 : 90;
|
||||
const statsQuery = useQuery({
|
||||
queryKey: ["dev-dashboard-stats"],
|
||||
@@ -1112,40 +1115,34 @@ function GlobalOverviewPage() {
|
||||
),
|
||||
[currentClientIdSet, recentClientChangesWithActors],
|
||||
);
|
||||
const recentChangeFilterOptions = useMemo<ClientFilterOption[]>(
|
||||
() => {
|
||||
const activeOptions = Array.from(
|
||||
new Map(
|
||||
recentClientChangesWithActors
|
||||
.filter((item) => currentClientIdSet.has(item.clientId))
|
||||
.map((item) => [
|
||||
item.clientId,
|
||||
{ id: item.clientId, label: item.clientName },
|
||||
]),
|
||||
).values(),
|
||||
).sort((left, right) => left.label.localeCompare(right.label));
|
||||
const recentChangeFilterOptions = useMemo<ClientFilterOption[]>(() => {
|
||||
const activeOptions = Array.from(
|
||||
new Map(
|
||||
recentClientChangesWithActors
|
||||
.filter((item) => currentClientIdSet.has(item.clientId))
|
||||
.map((item) => [
|
||||
item.clientId,
|
||||
{ id: item.clientId, label: item.clientName },
|
||||
]),
|
||||
).values(),
|
||||
).sort((left, right) => left.label.localeCompare(right.label));
|
||||
|
||||
if (deletedRecentChangeClientIds.length === 0) {
|
||||
return activeOptions;
|
||||
}
|
||||
if (deletedRecentChangeClientIds.length === 0) {
|
||||
return activeOptions;
|
||||
}
|
||||
|
||||
return [
|
||||
...activeOptions,
|
||||
{
|
||||
id: deletedRecentChangeFilterId,
|
||||
label: t(
|
||||
"ui.dev.dashboard.recent_changes.deleted_group",
|
||||
"삭제된 앱",
|
||||
),
|
||||
},
|
||||
];
|
||||
},
|
||||
[
|
||||
currentClientIdSet,
|
||||
deletedRecentChangeClientIds.length,
|
||||
recentClientChangesWithActors,
|
||||
],
|
||||
);
|
||||
return [
|
||||
...activeOptions,
|
||||
{
|
||||
id: deletedRecentChangeFilterId,
|
||||
label: t("ui.dev.dashboard.recent_changes.deleted_group", "삭제된 앱"),
|
||||
},
|
||||
];
|
||||
}, [
|
||||
currentClientIdSet,
|
||||
deletedRecentChangeClientIds.length,
|
||||
recentClientChangesWithActors,
|
||||
]);
|
||||
const filteredRecentClientChanges = useMemo(() => {
|
||||
if (selectedRecentChangeClientIds.length === 0) {
|
||||
return recentClientChangesWithActors;
|
||||
@@ -1155,7 +1152,8 @@ function GlobalOverviewPage() {
|
||||
return recentClientChangesWithActors.filter(
|
||||
(item) =>
|
||||
selectedSet.has(item.clientId) ||
|
||||
(includeDeletedGroup && deletedRecentChangeClientIds.includes(item.clientId)),
|
||||
(includeDeletedGroup &&
|
||||
deletedRecentChangeClientIds.includes(item.clientId)),
|
||||
);
|
||||
}, [
|
||||
deletedRecentChangeClientIds,
|
||||
@@ -1163,7 +1161,8 @@ function GlobalOverviewPage() {
|
||||
selectedRecentChangeClientIds,
|
||||
]);
|
||||
const selectedRecentChangeSeries = useMemo(
|
||||
() => buildRecentChangeSeries(filteredRecentClientChanges, recentChangesPeriod),
|
||||
() =>
|
||||
buildRecentChangeSeries(filteredRecentClientChanges, recentChangesPeriod),
|
||||
[filteredRecentClientChanges, recentChangesPeriod],
|
||||
);
|
||||
const recentChangedClientCount = useMemo(
|
||||
@@ -1180,7 +1179,9 @@ function GlobalOverviewPage() {
|
||||
new Set(
|
||||
filteredRecentClientChanges
|
||||
.map((item) => item.clientId)
|
||||
.filter((clientId) => deletedRecentChangeClientIds.includes(clientId)),
|
||||
.filter((clientId) =>
|
||||
deletedRecentChangeClientIds.includes(clientId),
|
||||
),
|
||||
).size,
|
||||
[deletedRecentChangeClientIds, filteredRecentClientChanges],
|
||||
);
|
||||
@@ -1251,10 +1252,10 @@ function GlobalOverviewPage() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setVisibleRecentClientChangesCount((current) =>
|
||||
Math.min(Math.max(6, current), filteredRecentClientChanges.length),
|
||||
);
|
||||
}, [filteredRecentClientChanges.length, selectedRecentChangeClientIds]);
|
||||
setVisibleRecentClientChangesCount((current) =>
|
||||
Math.min(Math.max(6, current), filteredRecentClientChanges.length),
|
||||
);
|
||||
}, [filteredRecentClientChanges.length]);
|
||||
|
||||
if (isLoadingDeveloperAccessGate) {
|
||||
return (
|
||||
@@ -1466,9 +1467,9 @@ function GlobalOverviewPage() {
|
||||
<OverviewMetric
|
||||
icon={<Layers3 size={14} />}
|
||||
label={t(
|
||||
"ui.dev.dashboard.recent_changes.summary.deleted_clients",
|
||||
"삭제된 앱 수",
|
||||
)}
|
||||
"ui.dev.dashboard.recent_changes.summary.deleted_clients",
|
||||
"삭제된 앱 수",
|
||||
)}
|
||||
value={deletedRecentChangedClientCount.toLocaleString()}
|
||||
/>
|
||||
<OverviewMetric
|
||||
@@ -1533,8 +1534,9 @@ function GlobalOverviewPage() {
|
||||
</div>
|
||||
) : (
|
||||
visibleRecentClientChanges.map((item) => {
|
||||
const { date, time } =
|
||||
formatRecentChangeTimestamp(item.timestamp);
|
||||
const { date, time } = formatRecentChangeTimestamp(
|
||||
item.timestamp,
|
||||
);
|
||||
return (
|
||||
<div
|
||||
key={item.eventId}
|
||||
@@ -1600,7 +1602,6 @@ function GlobalOverviewPage() {
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,9 @@ describe("recent client changes", () => {
|
||||
mockLocale("en");
|
||||
|
||||
expect(getRecentClientActionLabel("CREATE_CLIENT")).toBe("App creation");
|
||||
expect(getRecentClientActionLabel("UPDATE_CLIENT")).toBe("Settings changes");
|
||||
expect(getRecentClientActionLabel("UPDATE_CLIENT")).toBe(
|
||||
"Settings changes",
|
||||
);
|
||||
expect(getRecentClientActionLabel("UPDATE_CLIENT_STATUS")).toBe(
|
||||
"Status changes",
|
||||
);
|
||||
@@ -64,7 +66,9 @@ describe("recent client changes", () => {
|
||||
"Client secret rotation",
|
||||
);
|
||||
expect(getRecentClientActionLabel("ADD_RELATION")).toBe("Add Relationship");
|
||||
expect(getRecentClientActionLabel("REMOVE_RELATION")).toBe("Remove");
|
||||
expect(getRecentClientActionLabel("REMOVE_RELATION")).toBe(
|
||||
"Remove Relationship",
|
||||
);
|
||||
expect(getRecentClientActionLabel("DELETE_CLIENT")).toBe("App deletion");
|
||||
expect(getRecentClientActionLabel("OTHER_ACTION")).toBe("OTHER_ACTION");
|
||||
|
||||
@@ -90,59 +94,107 @@ describe("recent client changes", () => {
|
||||
it("builds recent client changes with sorting, filtering, and detail slicing", () => {
|
||||
mockLocale("ko");
|
||||
|
||||
const clients = [makeClient("client-a", "Alpha"), makeClient("client-b", "")];
|
||||
const clients = [
|
||||
makeClient("client-a", "Alpha"),
|
||||
makeClient("client-b", ""),
|
||||
];
|
||||
const auditLogs = [
|
||||
makeAuditLog("evt-1", "2026-05-27T07:00:00.000Z", "CREATE_CLIENT", "client-a", {
|
||||
after: { name: "Alpha", type: "private", status: "active" },
|
||||
}),
|
||||
makeAuditLog("evt-2", "2026-05-27T08:00:00.000Z", "UPDATE_CLIENT", "client-a", {
|
||||
before: {
|
||||
name: "Alpha old",
|
||||
status: "inactive",
|
||||
sameField: "same",
|
||||
oldField: "old-value",
|
||||
makeAuditLog(
|
||||
"evt-1",
|
||||
"2026-05-27T07:00:00.000Z",
|
||||
"CREATE_CLIENT",
|
||||
"client-a",
|
||||
{
|
||||
after: { name: "Alpha", type: "private", status: "active" },
|
||||
},
|
||||
after: {
|
||||
name: "Alpha new",
|
||||
status: "active",
|
||||
sameField: "same",
|
||||
newField: "new-value",
|
||||
),
|
||||
makeAuditLog(
|
||||
"evt-2",
|
||||
"2026-05-27T08:00:00.000Z",
|
||||
"UPDATE_CLIENT",
|
||||
"client-a",
|
||||
{
|
||||
before: {
|
||||
name: "Alpha old",
|
||||
status: "inactive",
|
||||
sameField: "same",
|
||||
oldField: "old-value",
|
||||
},
|
||||
after: {
|
||||
name: "Alpha new",
|
||||
status: "active",
|
||||
sameField: "same",
|
||||
newField: "new-value",
|
||||
},
|
||||
},
|
||||
}),
|
||||
makeAuditLog("evt-3", "2026-05-27T09:00:00.000Z", "UPDATE_CLIENT_STATUS", "client-a", {
|
||||
before: { status: "inactive" },
|
||||
after: { status: "active" },
|
||||
}),
|
||||
makeAuditLog("evt-4", "2026-05-27T10:00:00.000Z", "ADD_RELATION", "client-b", {
|
||||
after: {
|
||||
relation: "audit_viewer",
|
||||
subject: "User:89692983-f512-4d96-845d-ac6123d08b95",
|
||||
),
|
||||
makeAuditLog(
|
||||
"evt-3",
|
||||
"2026-05-27T09:00:00.000Z",
|
||||
"UPDATE_CLIENT_STATUS",
|
||||
"client-a",
|
||||
{
|
||||
before: { status: "inactive" },
|
||||
after: { status: "active" },
|
||||
},
|
||||
}),
|
||||
makeAuditLog("evt-5", "2026-05-27T11:00:00.000Z", "REMOVE_RELATION", "client-b", {
|
||||
before: {
|
||||
relation: "admins",
|
||||
subject: "User:89692983-f512-4d96-845d-ac6123d08b95",
|
||||
),
|
||||
makeAuditLog(
|
||||
"evt-4",
|
||||
"2026-05-27T10:00:00.000Z",
|
||||
"ADD_RELATION",
|
||||
"client-b",
|
||||
{
|
||||
after: {
|
||||
relation: "audit_viewer",
|
||||
subject: "User:89692983-f512-4d96-845d-ac6123d08b95",
|
||||
},
|
||||
},
|
||||
}),
|
||||
makeAuditLog("evt-6", "2026-05-27T12:00:00.000Z", "ROTATE_SECRET", "client-a", {
|
||||
after: {},
|
||||
}),
|
||||
makeAuditLog("evt-7", "2026-05-27T13:00:00.000Z", "DELETE_CLIENT", "client-a", {
|
||||
before: {
|
||||
name: "Alpha",
|
||||
status: "inactive",
|
||||
),
|
||||
makeAuditLog(
|
||||
"evt-5",
|
||||
"2026-05-27T11:00:00.000Z",
|
||||
"REMOVE_RELATION",
|
||||
"client-b",
|
||||
{
|
||||
before: {
|
||||
relation: "admins",
|
||||
subject: "User:89692983-f512-4d96-845d-ac6123d08b95",
|
||||
},
|
||||
},
|
||||
}),
|
||||
makeAuditLog("evt-8", "2026-05-27T14:00:00.000Z", "UNSUPPORTED_ACTION", "client-a", {
|
||||
after: { name: "Ignored" },
|
||||
}),
|
||||
),
|
||||
makeAuditLog(
|
||||
"evt-6",
|
||||
"2026-05-27T12:00:00.000Z",
|
||||
"ROTATE_SECRET",
|
||||
"client-a",
|
||||
{
|
||||
after: {},
|
||||
},
|
||||
),
|
||||
makeAuditLog(
|
||||
"evt-7",
|
||||
"2026-05-27T13:00:00.000Z",
|
||||
"DELETE_CLIENT",
|
||||
"client-a",
|
||||
{
|
||||
before: {
|
||||
name: "Alpha",
|
||||
status: "inactive",
|
||||
},
|
||||
},
|
||||
),
|
||||
makeAuditLog(
|
||||
"evt-8",
|
||||
"2026-05-27T14:00:00.000Z",
|
||||
"UNSUPPORTED_ACTION",
|
||||
"client-a",
|
||||
{
|
||||
after: { name: "Ignored" },
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
const changes = buildRecentClientChanges(
|
||||
auditLogs,
|
||||
clients,
|
||||
);
|
||||
const changes = buildRecentClientChanges(auditLogs, clients);
|
||||
|
||||
expect(changes).toHaveLength(7);
|
||||
expect(changes[0]).toMatchObject({
|
||||
@@ -164,7 +216,7 @@ describe("recent client changes", () => {
|
||||
expect(changes[2]).toMatchObject({
|
||||
eventId: "evt-5",
|
||||
clientName: "client-b",
|
||||
actionLabel: "제외",
|
||||
actionLabel: "관계 삭제",
|
||||
detailLabels: [
|
||||
{ label: "관계", value: "admins" },
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ export function getRecentClientActionLabel(action: string) {
|
||||
case "ADD_RELATION":
|
||||
return t("ui.dev.clients.relationships.add_title", "관계 추가");
|
||||
case "REMOVE_RELATION":
|
||||
return t("ui.common.remove", "Remove");
|
||||
return t("ui.dev.clients.relationships.remove_title", "관계 삭제");
|
||||
case "DELETE_CLIENT":
|
||||
return t("ui.dev.clients.recent_changes.guide.delete", "앱 삭제");
|
||||
default:
|
||||
@@ -68,7 +68,7 @@ function getRecentClientFieldLabel(key: string) {
|
||||
case "relation":
|
||||
return t("ui.dev.clients.relationships.relation", "관계");
|
||||
case "subject":
|
||||
return t("ui.dev.clients.relationships.subject", "대상");
|
||||
return t("ui.dev.clients.relationships.subject", "주체");
|
||||
case "client_secret":
|
||||
return t(
|
||||
"ui.dev.clients.details.credentials.client_secret",
|
||||
|
||||
Reference in New Issue
Block a user