整理测试代码并清理文档引用
This commit is contained in:
@@ -1,68 +0,0 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const readDetail = () => readFileSync(resolve(__dirname, "./ContractFeeDetail.vue"), "utf8");
|
||||
|
||||
describe("ContractFeeDetail permissions", () => {
|
||||
it("suppresses optional site lookup permission errors on the detail page", () => {
|
||||
const source = readDetail();
|
||||
|
||||
expect(source).toContain('fetchSites(studyId.value, { limit: 500 }, { suppressErrorMessage: true })');
|
||||
});
|
||||
|
||||
it("opens the edit drawer on the detail page without navigating back to the list", () => {
|
||||
const source = readDetail();
|
||||
|
||||
expect(source).toContain("<ContractFeeEditorDrawer");
|
||||
expect(source).toContain("editorVisible.value = true");
|
||||
expect(source).toContain("const handleEditorSaved = () =>");
|
||||
expect(source).not.toContain('router.push({ path: "/fees/contracts"');
|
||||
expect(source).not.toContain("editContractId");
|
||||
});
|
||||
|
||||
it("renders contract fee attachments as one aggregated table with attachment type labels", () => {
|
||||
const source = readDetail();
|
||||
|
||||
expect(source).toContain("<AttachmentList");
|
||||
expect(source).toContain(":entity-groups=\"attachmentGroups\"");
|
||||
expect(source).toContain(":refresh-key=\"attachmentRefreshKey\"");
|
||||
expect(source).toContain("attachmentRefreshKey.value += 1");
|
||||
expect(source).not.toContain("<FeeAttachmentPanel");
|
||||
expect(source).toContain('entityType: "contract_fee_contract"');
|
||||
expect(source).toContain('entityType: "contract_fee_voucher"');
|
||||
expect(source).toContain('entityType: "contract_fee_invoice"');
|
||||
});
|
||||
|
||||
it("does not show attachment group descriptions on the detail page", () => {
|
||||
const source = readDetail();
|
||||
|
||||
expect(source).not.toContain("attachmentContractDesc");
|
||||
expect(source).not.toContain("attachmentVoucherDesc");
|
||||
expect(source).not.toContain("attachmentInvoiceDesc");
|
||||
});
|
||||
|
||||
it("keeps payment table columns evenly distributed with clear labels", () => {
|
||||
const source = readDetail();
|
||||
|
||||
expect(source).toContain('v-for="(payment, index) in detail.payments"');
|
||||
expect(source).toContain("TEXT.modules.feeContracts.paymentSeq");
|
||||
expect(source).toContain("TEXT.modules.feeContracts.paidFlag");
|
||||
expect(source).toContain("TEXT.modules.feeContracts.verifiedFlag");
|
||||
expect(source).toContain("tl-panel-amount");
|
||||
expect(source).not.toContain('width="20%"');
|
||||
expect(source).not.toContain(".payment-table :deep(col:nth-child(-n + 5))");
|
||||
});
|
||||
|
||||
it("uses ten-thousand yuan as the only amount unit and hides currency", () => {
|
||||
const source = readDetail();
|
||||
|
||||
expect(source).toContain("formatAmountWan(detail.contract_amount)");
|
||||
expect(source).toContain("formatAmountWan(payment.amount)");
|
||||
expect(source).toContain('<span class="stat-tile-unit">万</span>');
|
||||
expect(source).toContain('<span class="amount-unit-sm">万</span>');
|
||||
expect(source).not.toContain("TEXT.common.fields.currency");
|
||||
expect(source).not.toContain("detail.currency");
|
||||
expect(source).not.toContain("currencyDefault");
|
||||
});
|
||||
});
|
||||
@@ -1,88 +0,0 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const readDrawer = () => readFileSync(resolve(__dirname, "./ContractFeeEditorDrawer.vue"), "utf8");
|
||||
const readLocale = () => readFileSync(resolve(__dirname, "../../locales/zh-CN.ts"), "utf8");
|
||||
|
||||
describe("ContractFeeEditorDrawer attachments", () => {
|
||||
it("uses upload-card mode for attachments instead of the detail table", () => {
|
||||
const source = readDrawer();
|
||||
|
||||
expect(source).toContain('ref="attachmentPanelRef"');
|
||||
expect(source).toContain("<AttachmentList");
|
||||
expect(source).toContain(":entity-groups=\"attachmentGroups\"");
|
||||
expect(source).not.toContain("PendingAttachmentUpload");
|
||||
expect(source).not.toContain("FeeAttachmentPanel");
|
||||
expect(source).not.toContain("attachmentContractDesc");
|
||||
expect(source).not.toContain("attachmentVoucherDesc");
|
||||
expect(source).not.toContain("attachmentInvoiceDesc");
|
||||
});
|
||||
|
||||
it("uploads selected attachments only after the form save succeeds", () => {
|
||||
const source = readDrawer();
|
||||
|
||||
expect(source).toContain("const attachmentPanelRef = ref<InstanceType<typeof AttachmentList> | null>(null)");
|
||||
expect(source).toContain("await attachmentPanelRef.value?.uploadPending(savedId)");
|
||||
expect(source).toContain("attachments: attachmentPanelRef.value?.pendingSnapshot() || []");
|
||||
expect(source.indexOf("await attachmentPanelRef.value?.uploadPending(savedId)")).toBeLessThan(
|
||||
source.indexOf('emit("update:modelValue", false)')
|
||||
);
|
||||
});
|
||||
|
||||
it("shows attachment upload cards while creating a new contract fee", () => {
|
||||
const source = readDrawer();
|
||||
|
||||
expect(source).toContain('class="form-section"');
|
||||
expect(source).toContain(':entity-id="form.id"');
|
||||
expect(source).toContain("<AttachmentList");
|
||||
expect(source).toContain(':center-upload-card-content="true"');
|
||||
expect(source).toContain(':upload-card-columns="3"');
|
||||
expect(source).not.toContain(':hide-upload-card-labels="true"');
|
||||
expect(source).not.toContain('<div v-if="form.id" class="form-group">');
|
||||
});
|
||||
|
||||
it("uses centered three-column upload cards with contract-specific copy", () => {
|
||||
const source = readDrawer();
|
||||
|
||||
expect(source).toContain('uploadText: "点击上传合同"');
|
||||
expect(source).toContain('uploadText: "点击上传凭证"');
|
||||
expect(source).toContain('uploadText: "点击上传发票"');
|
||||
expect(source).toContain(':center-upload-card-content="true"');
|
||||
expect(source).toContain(':upload-card-columns="3"');
|
||||
expect(source).not.toContain(':hide-upload-card-labels="true"');
|
||||
});
|
||||
|
||||
it("labels the section as attachments instead of contract attachments", () => {
|
||||
const source = readLocale();
|
||||
|
||||
expect(source).toContain('attachmentTitle: "附件"');
|
||||
expect(source).not.toContain('attachmentTitle: "合同附件"');
|
||||
});
|
||||
|
||||
it("uses a payment grid that keeps date pickers inside their columns", () => {
|
||||
const source = readDrawer();
|
||||
|
||||
expect(source).toContain('class="field-grid field-grid--3"');
|
||||
expect(source).toContain('class="status-row"');
|
||||
expect(source).toContain('class="status-datepicker"');
|
||||
expect(source).toContain("grid-template-columns: 1fr 1fr 1fr;");
|
||||
expect(source).toContain("min-width: 0;");
|
||||
expect(source).toContain(".status-datepicker :deep(.el-date-editor.el-input)");
|
||||
});
|
||||
|
||||
it("uses ten-thousand yuan as the only amount unit and removes currency selection", () => {
|
||||
const source = readDrawer();
|
||||
|
||||
expect(source).toContain(':label="`${TEXT.modules.feeContracts.contractAmount}(万元)`"');
|
||||
expect(source).toContain(':label="`${TEXT.common.fields.amount}(万元)`"');
|
||||
expect(source).toContain("contract_amount: Number(detail.contract_amount || 0) / 10000");
|
||||
expect(source).toContain("amount: Number(payment.amount || 0) / 10000");
|
||||
expect(source).toContain("contract_amount: Number(form.contract_amount || 0) * 10000");
|
||||
expect(source).toContain("amount: Number(payment.amount || 0) * 10000");
|
||||
expect(source).not.toContain("prop=\"currency\"");
|
||||
expect(source).not.toContain("form.currency");
|
||||
expect(source).not.toContain("payload.currency");
|
||||
expect(source).not.toContain("currency:");
|
||||
});
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { TEXT } from "../../locales";
|
||||
|
||||
describe("contract fee attachment labels", () => {
|
||||
it("uses a concise attachment section title", () => {
|
||||
expect(TEXT.modules.feeContracts.attachmentTitle).toBe("附件");
|
||||
});
|
||||
|
||||
it("uses a clear payment sequence column label", () => {
|
||||
expect(TEXT.modules.feeContracts.paymentSeqColumn).toBe("付款期次");
|
||||
expect(TEXT.modules.feeContracts.paymentSeq).toBe("第");
|
||||
});
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const read = (relativePath: string) => readFileSync(resolve(__dirname, relativePath), "utf8");
|
||||
|
||||
describe("Contract fee project permissions", () => {
|
||||
it("hides list create/delete controls when the matching backend operation is not allowed", () => {
|
||||
const source = read("./ContractFees.vue");
|
||||
|
||||
expect(source).toContain('v-if="canCreate"');
|
||||
expect(source).toContain('v-if="canDelete"');
|
||||
expect(source).toContain("if (!canCreate.value)");
|
||||
expect(source).toContain("if (!canDelete.value)");
|
||||
expect(source).not.toContain(':disabled="!canCreate"');
|
||||
expect(source).not.toContain(':disabled="!canDelete || isInactiveSite(scope.row.center_id)"');
|
||||
});
|
||||
|
||||
it("hides detail edit controls and blocks direct navigation without update permission", () => {
|
||||
const source = read("./ContractFeeDetail.vue");
|
||||
|
||||
expect(source).toContain('v-if="canWrite"');
|
||||
expect(source).toContain("if (!canWrite.value)");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user