1
0
forked from baron/baron-sso

orgfront 버그 픽스

This commit is contained in:
2026-06-10 09:36:57 +09:00
parent 28478309fa
commit c880b3c333
33 changed files with 853 additions and 130 deletions

View File

@@ -143,6 +143,7 @@ vi.mock("../../lib/adminApi", () => ({
login_count: 3,
},
]),
fetchGlobalCustomClaimDefinitions: vi.fn(async () => ({ items: [] })),
fetchPasswordPolicy: vi.fn(async () => ({
minLength: 12,
lowercase: true,
@@ -196,6 +197,7 @@ vi.mock("../../lib/adminApi", () => ({
worksmobileId: "works-user-1",
worksmobileName: "Engineer User",
worksmobileEmail: "engineer@example.com",
worksmobileDomainId: 1001,
worksmobilePrimaryOrgId: "works-org-1",
worksmobilePrimaryOrgName: "기술연구팀",
status: "matched",
@@ -380,17 +382,19 @@ describe("adminfront large page coverage smoke", () => {
fireEvent.click(
screen.getByRole("button", { name: "선택 구성원 WORKS에 생성" }),
);
fireEvent.change(screen.getByLabelText("초기 비밀번호"), {
target: { value: "InitialPassword!1" },
});
fireEvent.click(screen.getByRole("button", { name: "생성 작업 등록" }));
await waitFor(() =>
expect(adminApi.enqueueWorksmobileUserSync).toHaveBeenCalledWith(
"tenant-company",
"user-2",
expect.any(String),
undefined,
"InitialPassword!1",
),
);
const credentialBatchId = vi.mocked(
adminApi.enqueueWorksmobileUserSync,
).mock.calls[0][2];
expect(adminApi.downloadWorksmobileInitialPasswordsCSV).not.toHaveBeenCalled();
});
@@ -416,6 +420,10 @@ describe("adminfront large page coverage smoke", () => {
fireEvent.click(
screen.getByRole("button", { name: "선택 구성원 WORKS에 생성" }),
);
fireEvent.change(screen.getByLabelText("초기 비밀번호"), {
target: { value: "InitialPassword!1" },
});
fireEvent.click(screen.getByRole("button", { name: "생성 작업 등록" }));
await waitFor(() =>
expect(adminApi.enqueueWorksmobileUserSync).toHaveBeenCalledTimes(2),
@@ -424,21 +432,20 @@ describe("adminfront large page coverage smoke", () => {
1,
"tenant-company",
"user-2",
expect.any(String),
undefined,
"InitialPassword!1",
);
expect(adminApi.enqueueWorksmobileUserSync).toHaveBeenNthCalledWith(
2,
"tenant-company",
"user-3",
expect.any(String),
undefined,
"InitialPassword!1",
);
expect(adminApi.downloadWorksmobileInitialPasswordsCSV).not.toHaveBeenCalled();
});
it("downloads or deletes Worksmobile credential batches from history", async () => {
vi.spyOn(window.URL, "createObjectURL").mockReturnValue("blob:test");
vi.spyOn(window.URL, "revokeObjectURL").mockImplementation(() => {});
vi.spyOn(window, "confirm").mockReturnValue(true);
it("renders and retries Worksmobile jobs from history", async () => {
renderWithProviders(
<Routes>
<Route
@@ -450,45 +457,20 @@ describe("adminfront large page coverage smoke", () => {
);
fireEvent.click(screen.getByRole("tab", { name: "이력" }));
await screen.findByText("credential-batch-1");
expect(
screen.getByRole("button", {
name: "credential-batch-pending 비밀번호 CSV 다운로드",
}),
).toBeDisabled();
fireEvent.click(
screen.getByRole("button", {
name: "credential-batch-1 비밀번호 CSV 다운로드",
}),
);
await waitFor(() =>
expect(
adminApi.downloadWorksmobileInitialPasswordsCSV,
).toHaveBeenCalledWith("tenant-company", "credential-batch-1"),
);
expect((await screen.findAllByText("user-1")).length).toBeGreaterThan(0);
expect(screen.getByText("failed")).toBeInTheDocument();
fireEvent.click(
screen.getByRole("button", {
name: "credential-batch-1 비밀번호 값 삭제",
}),
);
fireEvent.click(screen.getAllByRole("button", { name: "" })[0]);
await waitFor(() =>
expect(
adminApi.deleteWorksmobileCredentialBatchPasswords,
).toHaveBeenCalledWith("tenant-company", "credential-batch-1"),
expect(adminApi.retryWorksmobileJob).toHaveBeenCalledWith(
"tenant-company",
"job-1",
),
);
fireEvent.click(
screen.getByRole("button", {
name: "credential-batch-1 실패 사유 보기",
}),
);
expect(await screen.findByText("failed-user@samaneng.com")).toBeInTheDocument();
expect(screen.getByText("worksmobile api failed")).toBeInTheDocument();
});
it("enqueues Worksmobile password reset as a credential batch", async () => {
vi.spyOn(window, "confirm").mockReturnValue(true);
it("opens Worksmobile password management for matched users", async () => {
const openSpy = vi.spyOn(window, "open").mockReturnValue(null);
renderWithProviders(
<Routes>
<Route
@@ -504,17 +486,21 @@ describe("adminfront large page coverage smoke", () => {
await screen.findAllByText("Engineer User");
fireEvent.click(
screen.getByRole("button", {
name: "Engineer User 비밀번호 재설정",
name: "Engineer User 비밀번호 관리",
}),
);
await waitFor(() =>
expect(adminApi.resetWorksmobileUserPassword).toHaveBeenCalledWith(
"tenant-company",
"user-1",
expect.any(String),
expect(openSpy).toHaveBeenCalledWith(
expect.stringContaining(
"https://auth.worksmobile.com/integrate/password/manage",
),
"_blank",
"noopener,noreferrer",
);
expect(adminApi.downloadWorksmobileInitialPasswordsCSV).not.toHaveBeenCalled();
const [url] = openSpy.mock.calls[0] ?? [];
const parsed = new URL(String(url));
expect(parsed.searchParams.get("targetUserTenantId")).toBe("works-admin");
expect(parsed.searchParams.get("targetUserDomainId")).toBe("1001");
expect(parsed.searchParams.get("targetUserIdNo")).toBe("works-user-1");
});
});

View File

@@ -149,9 +149,13 @@ describe("DataIntegrityPage", () => {
it("renders Ory SSOT cache management inside data integrity", async () => {
renderPage();
fireEvent.click(await screen.findByRole("tab", { name: "Ory SSOT 시스템" }));
fireEvent.click(
await screen.findByRole("tab", { name: "Ory SSOT 시스템" }),
);
expect((await screen.findAllByText("Ory SSOT 시스템")).length).toBeGreaterThan(0);
expect(
(await screen.findAllByText("Ory SSOT 시스템")).length,
).toBeGreaterThan(0);
expect(await screen.findByText("Redis identity cache")).toBeInTheDocument();
expect(screen.getAllByText("준비됨").length).toBeGreaterThan(0);
expect(screen.getByText("152")).toBeInTheDocument();

View File

@@ -84,7 +84,9 @@ describe("UserProjectionPage", () => {
await screen.findByText("Ory SSOT 시스템");
expect(screen.queryByRole("button", { name: /재동기화/ })).toBeNull();
expect(screen.queryByRole("button", { name: /초기화 후 재구축/ })).toBeNull();
expect(
screen.queryByRole("button", { name: /초기화 후 재구축/ }),
).toBeNull();
fireEvent.click(screen.getByRole("button", { name: /Redis cache flush/ }));
await waitFor(() => {

View File

@@ -209,6 +209,7 @@ export default function GlobalCustomClaimsPage() {
>
<Input
value={claim.key}
name={`global-claim-definition-key-${claim.id}`}
className="font-mono text-xs"
placeholder="claim_key"
data-testid={`global-claim-definition-key-${claim.key || claim.id}`}
@@ -218,6 +219,7 @@ export default function GlobalCustomClaimsPage() {
/>
<Input
value={claim.label}
name={`global-claim-definition-label-${claim.id}`}
placeholder={t(
"ui.admin.users.global_custom_claims.label_placeholder",
"표시 이름",
@@ -233,6 +235,7 @@ export default function GlobalCustomClaimsPage() {
"Claim 타입",
)}
value={claim.valueType}
name={`global-claim-definition-value-type-${claim.id}`}
className="h-10 rounded-md border border-input bg-background px-3 text-sm"
onChange={(event) =>
updateClaim(claim.id, {
@@ -253,6 +256,7 @@ export default function GlobalCustomClaimsPage() {
"읽기 권한",
)}
value={claim.readPermission}
name={`global-claim-definition-read-permission-${claim.id}`}
className="h-10 rounded-md border border-input bg-background px-3 text-sm"
data-testid={`global-claim-definition-read-permission-${claim.key || claim.id}`}
onChange={(event) =>
@@ -274,6 +278,7 @@ export default function GlobalCustomClaimsPage() {
"쓰기 권한",
)}
value={claim.writePermission}
name={`global-claim-definition-write-permission-${claim.id}`}
className="h-10 rounded-md border border-input bg-background px-3 text-sm"
data-testid={`global-claim-definition-write-permission-${claim.key || claim.id}`}
onChange={(event) =>
@@ -291,6 +296,7 @@ export default function GlobalCustomClaimsPage() {
</select>
<Input
value={claim.description || ""}
name={`global-claim-definition-description-${claim.id}`}
placeholder={t(
"ui.admin.users.global_custom_claims.description_placeholder",
"설명",

View File

@@ -186,7 +186,9 @@ describe("UserDetailPage Worksmobile employee number", () => {
expect(valueInput).toHaveAttribute("type", "date");
fireEvent.change(valueInput, { target: { value: "2026-07-01" } });
fireEvent.click(screen.getByRole("button", { name: /사용자 Claim 값 저장/ }));
fireEvent.click(
screen.getByRole("button", { name: /사용자 Claim 값 저장/ }),
);
await waitFor(() => expect(updateUserMock).toHaveBeenCalled());
expect(updateUserMock).toHaveBeenCalledWith(