NODEDC_1C/llm_normalizer/backend/tests/addressCounterpartyIntentSi...

76 lines
4.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { resolveCounterpartyAddressIntent } from "../src/services/addressCounterpartyIntentSignals";
import { resolveAddressIntent } from "../src/services/addressIntentResolver";
const defaultDeps = {
hasAny: (text: string, hints: readonly string[]) => hints.some((hint) => text.includes(hint)),
openItemsHints: ["хвост", "долг", "open items"],
openContractsHints: ["договор", "контракт", "open contracts"],
documentsByCounterpartyHints: ["документы по", "documents by counterparty"],
bankOperationsByCounterpartyHints: ["банк", "выписка", "bank operations by counterparty"],
documentsByContractHints: ["документы по договору", "documents by contract"],
hasCounterpartyDebtLongevitySignal: () => false,
hasInventoryAgingSignal: () => false,
hasInventoryProvenanceSignalV2: () => false,
hasInventoryPurchaseDocumentsSignalV2: () => false,
hasInventorySaleTraceSignalV2: () => false,
hasAccountNumberAnchor: (text: string) => /60/.test(text),
hasCompactAccountCodeToken: () => false,
hasPeriodCoverageProfileSignal: (text: string) => text.includes("year coverage"),
hasPartyAnchorMention: (text: string) => text.includes("чепурнов"),
hasContractAnchorSignal: (text: string) => text.includes("договор"),
hasAccountBalanceSignal: (text: string) => text.includes("balance by account"),
hasDocumentTypeAndAccountSectionProfileSignal: (text: string) => text.includes("document profile"),
hasCounterpartyPopulationAndRolesSignal: (text: string) => text.includes("population and roles"),
hasCounterpartyActivityLifecycleSignal: (text: string) => text.includes("activity lifecycle"),
hasContractUsageOverviewSignal: (text: string) => text.includes("usage overview"),
hasOpenContractsListSignal: (text: string) => text.includes("open contracts"),
hasCustomerRevenueAndPaymentsSignal: (text: string) => text.includes("revenue and payments"),
hasSupplierPayoutsProfileSignal: (text: string) => text.includes("supplier payouts"),
hasContractUsageAndValueSignal: (text: string) => text.includes("usage and value"),
hasContractListByCounterpartySignal: (text: string) => text.includes("contracts by counterparty"),
hasBankOperationSignal: (text: string) => text.includes("банк"),
hasDocumentSignal: (text: string) => text.includes("документ"),
hasLooseByAnchorMention: (text: string) => text.includes("по нему"),
hasHeuristicCounterpartyAnchor: (text: string) => text.includes("чепурнов"),
hasCounterpartyShipmentItemFlowSignal: (text: string) => text.includes("отгружал"),
hasImplicitCounterpartyAnchorAroundDocs: () => false,
hasGenericAddressLookupSignal: (text: string) => text.includes("покажи")
};
describe("addressCounterpartyIntentSignals", () => {
it("classifies open-items wording through the extracted counterparty owner", () => {
const result = resolveCounterpartyAddressIntent("хвосты покажи по счету 60 на август 2022", defaultDeps);
expect(result?.intent).toBe("open_items_by_counterparty_or_contract");
expect(result?.reasons).toContain("open_items_signal_detected");
});
it("classifies counterparty document-flow wording through the extracted counterparty owner", () => {
const result = resolveCounterpartyAddressIntent("что нам отгружал чепурнов", defaultDeps);
expect(result?.intent).toBe("list_documents_by_counterparty");
expect(result?.reasons).toContain("counterparty_item_flow_signal_detected");
});
it("classifies passive shipment wording with instrumental counterparty phrasing", () => {
const result = resolveAddressIntent("какие товары или услуги были отгружены нашей компании контрагентом чапурновым?");
expect(result.intent).toBe("list_documents_by_counterparty");
expect(result.reasons).toContain("counterparty_item_flow_signal_detected");
});
it("keeps the main resolver behavior stable through counterparty-owner delegation", () => {
const result = resolveAddressIntent("хвосты покажи по счету 60 на август 2022");
expect(result.intent).toBe("open_items_by_counterparty_or_contract");
});
it("does not steal inventory wording into the counterparty owner", () => {
const result = resolveCounterpartyAddressIntent("show inventory on hand as of 2020-03-15", defaultDeps);
expect(result).toBeNull();
});
});