55 行
2.4 KiB
JavaScript
55 行
2.4 KiB
JavaScript
const { suggestInvoiceExpenseType } = require("../../../src/services/invoiceExpenseClassification");
|
|
|
|
const enabledTypes = [
|
|
{ id: "train-type", code: "travel_train", enabled: true },
|
|
{ id: "hotel-type", code: "travel_hotel", enabled: true },
|
|
{ id: "meal-type", code: "business_client_meal", enabled: true },
|
|
];
|
|
|
|
function invoiceWithCategory(documentCategory, extra = {}) {
|
|
return { ocr_result: { result_json: { documentCategory } }, ...extra };
|
|
}
|
|
|
|
describe("invoice expense classification", () => {
|
|
it("suggests the enabled train type from a recognized electronic train ticket", () => {
|
|
expect(suggestInvoiceExpenseType(invoiceWithCategory("electronic_train_ticket"), enabledTypes))
|
|
.toEqual({ expenseTypeId: "train-type", source: "document_category" });
|
|
});
|
|
|
|
it.each(["vat_invoice", "full_vat_invoice", "unknown", null])(
|
|
"does not guess an expense type from category %s, seller, filename or amount",
|
|
(category) => {
|
|
expect(suggestInvoiceExpenseType(invoiceWithCategory(category, {
|
|
seller_name: "合成酒店餐饮公司",
|
|
original_name: "办公用品.pdf",
|
|
total_amount: "100.00",
|
|
}), enabledTypes)).toBeNull();
|
|
},
|
|
);
|
|
|
|
it("does not substitute another enabled type when the matching type is disabled", () => {
|
|
const expenseTypes = enabledTypes.map((type) => ({ ...type, enabled: type.code !== "travel_train" }));
|
|
expect(suggestInvoiceExpenseType(invoiceWithCategory("electronic_train_ticket"), expenseTypes)).toBeNull();
|
|
});
|
|
|
|
it("does not substitute the first enabled type when the matching type is absent", () => {
|
|
expect(suggestInvoiceExpenseType(invoiceWithCategory("electronic_train_ticket"), enabledTypes.slice(1)))
|
|
.toBeNull();
|
|
});
|
|
|
|
it("does not infer from the historical provider or generic upload type", () => {
|
|
expect(suggestInvoiceExpenseType({ ocr_provider: "tencent", ocr_type: "vat" }, enabledTypes)).toBeNull();
|
|
});
|
|
|
|
it("does not infer from client-facing category fields instead of persisted OCR metadata", () => {
|
|
expect(suggestInvoiceExpenseType({ documentCategory: "electronic_train_ticket" }, enabledTypes)).toBeNull();
|
|
});
|
|
|
|
it("does not mutate invoice data or expense types", () => {
|
|
const invoice = invoiceWithCategory("electronic_train_ticket");
|
|
const before = JSON.stringify({ invoice, enabledTypes });
|
|
suggestInvoiceExpenseType(invoice, enabledTypes);
|
|
expect(JSON.stringify({ invoice, enabledTypes })).toBe(before);
|
|
});
|
|
});
|