|
|
|
@@ -45,6 +45,8 @@ type MockScenario = {
|
|
|
|
|
businessDate: string | null;
|
|
|
|
|
summary: string | null;
|
|
|
|
|
}>;
|
|
|
|
|
paymentCandidateTotal?: number;
|
|
|
|
|
onCandidateQuery?: (query: URLSearchParams) => void;
|
|
|
|
|
contracts?: SyntheticContract[];
|
|
|
|
|
onCreatePaymentBatch?: (payload: unknown) => void;
|
|
|
|
|
};
|
|
|
|
@@ -156,7 +158,8 @@ function expectNoPageErrors(errors: string[]) {
|
|
|
|
|
async function mockSyntheticApis(page: Page, actor: SyntheticActor, scenario: MockScenario = {}) {
|
|
|
|
|
await page.route((url) => url.pathname.startsWith("/api/"), async (route) => {
|
|
|
|
|
const request = route.request();
|
|
|
|
|
const pathName = new URL(request.url()).pathname;
|
|
|
|
|
const requestUrl = new URL(request.url());
|
|
|
|
|
const pathName = requestUrl.pathname;
|
|
|
|
|
|
|
|
|
|
if (pathName === "/api/auth/capabilities") {
|
|
|
|
|
await fulfillJson(route, {
|
|
|
|
@@ -265,7 +268,13 @@ async function mockSyntheticApis(page: Page, actor: SyntheticActor, scenario: Mo
|
|
|
|
|
}
|
|
|
|
|
if (pathName === "/api/payment-batches/candidates") {
|
|
|
|
|
const items = scenario.paymentCandidates ?? [];
|
|
|
|
|
await fulfillJson(route, { items, page: 1, pageSize: 50, total: items.length });
|
|
|
|
|
scenario.onCandidateQuery?.(requestUrl.searchParams);
|
|
|
|
|
await fulfillJson(route, {
|
|
|
|
|
items,
|
|
|
|
|
page: Number(requestUrl.searchParams.get("page") ?? "1"),
|
|
|
|
|
pageSize: Number(requestUrl.searchParams.get("pageSize") ?? "20"),
|
|
|
|
|
total: scenario.paymentCandidateTotal ?? items.length,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (pathName === "/api/payment-batches" && request.method() === "POST") {
|
|
|
|
@@ -342,13 +351,18 @@ test("只有付款复核职责的经理可看应付账款但看不到导出", as
|
|
|
|
|
test("只有付款复核职责的经理看不到新建批次", async ({ page }) => {
|
|
|
|
|
test.skip(process.env.E2E_MODE === "live", "只使用本地合成角色,不访问公网");
|
|
|
|
|
const pageErrors = capturePageErrors(page);
|
|
|
|
|
await mockSyntheticApis(page, REVIEWER_ACTOR);
|
|
|
|
|
let candidateQueryCount = 0;
|
|
|
|
|
await mockSyntheticApis(page, REVIEWER_ACTOR, {
|
|
|
|
|
onCandidateQuery: () => { candidateQueryCount += 1; },
|
|
|
|
|
});
|
|
|
|
|
await login(page, REVIEWER_ACTOR);
|
|
|
|
|
|
|
|
|
|
await page.goto("/payment-batches");
|
|
|
|
|
await expect(page).toHaveURL(/\/payment-batches$/);
|
|
|
|
|
await page.goto("/payment-batches?view=pending");
|
|
|
|
|
await expect(page).toHaveURL(/\/payment-batches\?view=batches$/);
|
|
|
|
|
await expect(page.getByRole("heading", { level: 1, name: "付款", exact: true })).toBeVisible();
|
|
|
|
|
await expect(page.getByRole("button", { name: "新建批次", exact: true })).toHaveCount(0);
|
|
|
|
|
await expect(page.getByRole("button", { name: /待组批/ })).toHaveCount(0);
|
|
|
|
|
await expect(page.getByRole("button", { name: /付款批次/ })).toBeVisible();
|
|
|
|
|
expect(candidateQueryCount).toBe(0);
|
|
|
|
|
expectNoPageErrors(pageErrors);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@@ -394,8 +408,11 @@ test("财务从业务候选选择报销并使用所选实体创建付款批次",
|
|
|
|
|
test.skip(process.env.E2E_MODE === "live", "只使用本地合成角色,不访问公网");
|
|
|
|
|
const pageErrors = capturePageErrors(page);
|
|
|
|
|
let createPayload: unknown = null;
|
|
|
|
|
const candidateQueries: string[] = [];
|
|
|
|
|
await mockSyntheticApis(page, FINANCE_ACTOR, {
|
|
|
|
|
paymentCandidates: [PAYMENT_CANDIDATE],
|
|
|
|
|
paymentCandidateTotal: 21,
|
|
|
|
|
onCandidateQuery: (query) => candidateQueries.push(query.toString()),
|
|
|
|
|
onCreatePaymentBatch: (payload) => {
|
|
|
|
|
createPayload = payload;
|
|
|
|
|
},
|
|
|
|
@@ -403,9 +420,15 @@ test("财务从业务候选选择报销并使用所选实体创建付款批次",
|
|
|
|
|
await login(page, FINANCE_ACTOR);
|
|
|
|
|
|
|
|
|
|
await page.goto("/payment-batches");
|
|
|
|
|
await expect(page).toHaveURL(/\/payment-batches$/);
|
|
|
|
|
await expect(page).toHaveURL(/\/payment-batches\?view=pending$/);
|
|
|
|
|
await expect(page.getByRole("heading", { level: 1, name: "付款", exact: true })).toBeVisible();
|
|
|
|
|
await page.getByRole("button", { name: "新建批次", exact: true }).click();
|
|
|
|
|
await expect(page.getByRole("button", { name: "待组批 21", exact: true })).toHaveAttribute("aria-current", "page");
|
|
|
|
|
await expect(page.getByTestId("payment-batch-candidates")).toHaveCount(1);
|
|
|
|
|
await expect.poll(() => page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth)).toBeLessThanOrEqual(2);
|
|
|
|
|
await page.getByRole("button", { name: "下一页", exact: true }).click();
|
|
|
|
|
await expect(page).toHaveURL(/view=pending&page=2/);
|
|
|
|
|
await expect.poll(() => candidateQueries.some((query) => query.includes("page=2") && query.includes("pageSize=20"))).toBe(true);
|
|
|
|
|
await page.getByRole("button", { name: "上一页", exact: true }).click();
|
|
|
|
|
|
|
|
|
|
const candidateRow = page.getByTestId("payment-batch-candidate-row");
|
|
|
|
|
await expect(candidateRow).toContainText(PAYMENT_CANDIDATE.businessNo);
|
|
|
|
@@ -413,13 +436,17 @@ test("财务从业务候选选择报销并使用所选实体创建付款批次",
|
|
|
|
|
await expect(candidateRow).toContainText("¥1,280.50");
|
|
|
|
|
await expect(page.getByText(PAYMENT_CANDIDATE_ENTITY_ID, { exact: true })).toHaveCount(0);
|
|
|
|
|
await expect(page.locator('input[placeholder*="UUID"], input[placeholder*="uuid"], input[placeholder*="entityId"], input[placeholder*="内部 ID"], input[placeholder*="内部ID"]')).toHaveCount(0);
|
|
|
|
|
await page.getByTestId("payment-batch-candidate-search").fill(PAYMENT_CANDIDATE.businessNo);
|
|
|
|
|
await expect(page).toHaveURL(new RegExp(`view=pending&q=${PAYMENT_CANDIDATE.businessNo}`));
|
|
|
|
|
await page.setViewportSize({ width: 375, height: 812 });
|
|
|
|
|
await expect.poll(() => page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth)).toBeLessThanOrEqual(2);
|
|
|
|
|
|
|
|
|
|
await candidateRow.getByRole("checkbox").check();
|
|
|
|
|
await page.getByTestId("payment-batch-default-channel").selectOption("cash");
|
|
|
|
|
await expect(page.getByText("按现金提交负责人复核", { exact: false })).toBeVisible();
|
|
|
|
|
await page.getByRole("button", { name: "创建并提交复核", exact: true }).click();
|
|
|
|
|
|
|
|
|
|
await expect(page).toHaveURL(new RegExp(`/payment-batches\\?id=${CREATED_PAYMENT_BATCH_ID}$`));
|
|
|
|
|
await expect(page).toHaveURL(new RegExp(`/payment-batches\\?view=batches&id=${CREATED_PAYMENT_BATCH_ID}$`));
|
|
|
|
|
await expect(page.getByRole("heading", { level: 1, name: "付款", exact: true })).toBeVisible();
|
|
|
|
|
await expect(page.getByText("已提交付款复核,等待负责人处理", { exact: true })).toBeVisible();
|
|
|
|
|
expect(createPayload).toEqual({
|
|
|
|
|