NODEDC_1C/llm_normalizer/backend/tests/addressInventorySaleTraceSe...

145 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { afterEach, describe, expect, it, vi } from "vitest";
const { executeAddressMcpQueryMock } = vi.hoisted(() => ({
executeAddressMcpQueryMock: vi.fn()
}));
vi.mock("../src/services/addressMcpClient", async () => {
const actual = await vi.importActual<typeof import("../src/services/addressMcpClient")>(
"../src/services/addressMcpClient"
);
return {
...actual,
executeAddressMcpQuery: executeAddressMcpQueryMock
};
});
import { AddressQueryService } from "../src/services/addressQueryService";
afterEach(() => {
executeAddressMcpQueryMock.mockReset();
vi.restoreAllMocks();
});
describe("inventory sale trace selected-object regressions", () => {
const saleRow = {
Period: "2021-04-15T00:00:00Z",
Registrator: "Реализация товаров и услуг 00000000201 от 15.04.2021 0:00:00",
AccountDt: "62.01",
AccountKt: "41.01",
Amount: 165.83,
Quantity: 1,
SubcontoKt1: "Кромка с клеем 33 дуб ниагара 137 м",
SubcontoKt3: "Основной склад",
SubcontoDt1: "ООО \\Покупатель\\",
SubcontoDt2: "Договор реализации № 17 от 14.04.2021",
Organization: "ООО \\Альтернатива Плюс\\"
};
const followupContext = {
previous_intent: "inventory_purchase_provenance_for_item" as const,
previous_filters: {
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31",
item: "Кромка с клеем 33 дуб ниагара 137 м",
organization: "ООО \\Альтернатива Плюс\\"
},
previous_anchor_type: "item" as const,
previous_anchor_value: "Кромка с клеем 33 дуб ниагара 137 м"
};
it("keeps the full selected item for explicit selected-object buyer wording from the live log", async () => {
executeAddressMcpQueryMock.mockResolvedValueOnce({
fetched_rows: 1,
matched_rows: 1,
raw_rows: [saleRow],
rows: [],
error: null
});
const service = new AddressQueryService();
const result = await service.tryHandle('По выбранному объекту "Кромка с клеем 33 дуб ниагара 137 м": кому продали', {
followupContext
});
expect(result?.handled).toBe(true);
expect(result?.response_type).toBe("FACTUAL_LIST");
expect(result?.debug.detected_intent).toBe("inventory_sale_trace_for_item");
expect(result?.debug.extracted_filters?.item).toBe("Кромка с клеем 33 дуб ниагара 137 м");
expect(String(result?.reply_text ?? "")).toContain("ООО \\Покупатель\\");
expect(executeAddressMcpQueryMock).toHaveBeenCalledTimes(1);
const query = String(executeAddressMcpQueryMock.mock.calls[0]?.[0]?.query ?? "");
expect(query).toContain("Документ.РеализацияТоваровУслуг.Товары КАК Товары");
expect(query).toContain("ПРЕДСТАВЛЕНИЕ(Товары.Ссылка.Контрагент) КАК Контрагент");
expect(query).toContain("Товары.Номенклатура В (ВЫБРАТЬ Номенклатура.Ссылка");
expect(query).toContain('Номенклатура.Наименование = "Кромка с клеем 33 дуб ниагара 137 м"');
expect(query).not.toContain('Номенклатура.Наименование = "Кромка"');
});
it("routes selected-object delivery wording 'кому мы это поставили' into sale trace", async () => {
executeAddressMcpQueryMock.mockResolvedValueOnce({
fetched_rows: 1,
matched_rows: 1,
raw_rows: [saleRow],
rows: [],
error: null
});
const service = new AddressQueryService();
const result = await service.tryHandle(
'По выбранному объекту "Кромка с клеем 33 дуб ниагара 137 м": кому мы это поставили',
{
followupContext: {
previous_intent: "inventory_on_hand_as_of_date",
previous_filters: {
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31",
organization: "ООО \\Альтернатива Плюс\\"
},
previous_anchor_type: "unknown",
previous_anchor_value: null
}
}
);
expect(result?.handled).toBe(true);
expect(result?.response_type).toBe("FACTUAL_LIST");
expect(result?.debug.detected_intent).toBe("inventory_sale_trace_for_item");
expect(result?.debug.extracted_filters?.item).toBe("Кромка с клеем 33 дуб ниагара 137 м");
expect(String(result?.reply_text ?? "")).toContain("ООО \\Покупатель\\");
});
it("keeps the full selected item for canonical selected-object buyer wording", async () => {
executeAddressMcpQueryMock.mockResolvedValueOnce({
fetched_rows: 1,
matched_rows: 1,
raw_rows: [saleRow],
rows: [],
error: null
});
const service = new AddressQueryService();
const result = await service.tryHandle(
"Определить контрагента, которому была продана позиция «Кромка с клеем 33 дуб ниагара 137 м» по выбранному объекту",
{ followupContext }
);
expect(result?.handled).toBe(true);
expect(result?.response_type).toBe("FACTUAL_LIST");
expect(result?.debug.detected_intent).toBe("inventory_sale_trace_for_item");
expect(result?.debug.extracted_filters?.item).toBe("Кромка с клеем 33 дуб ниагара 137 м");
expect(String(result?.reply_text ?? "")).toContain("ООО \\Покупатель\\");
expect(executeAddressMcpQueryMock).toHaveBeenCalledTimes(1);
const query = String(executeAddressMcpQueryMock.mock.calls[0]?.[0]?.query ?? "");
expect(query).toContain("Документ.РеализацияТоваровУслуг.Товары КАК Товары");
expect(query).toContain("ПРЕДСТАВЛЕНИЕ(Товары.Ссылка.Контрагент) КАК Контрагент");
expect(query).toContain("Товары.Номенклатура В (ВЫБРАТЬ Номенклатура.Ссылка");
expect(query).toContain('Номенклатура.Наименование = "Кромка с клеем 33 дуб ниагара 137 м"');
expect(query).not.toContain('Номенклатура.Наименование = "Кромка"');
});
});