108 lines
4.3 KiB
TypeScript
108 lines
4.3 KiB
TypeScript
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";
|
||
import { runAddressDecomposeStage } from "../src/services/address_runtime/decomposeStage";
|
||
|
||
afterEach(() => {
|
||
executeAddressMcpQueryMock.mockReset();
|
||
vi.restoreAllMocks();
|
||
});
|
||
|
||
describe("inventory profitability selected-object regressions", () => {
|
||
const followupContext = {
|
||
previous_intent: "inventory_on_hand_as_of_date" as const,
|
||
previous_filters: {
|
||
organization: "ООО \\Альтернатива Плюс\\",
|
||
as_of_date: "2020-05-31",
|
||
period_from: "2020-05-01",
|
||
period_to: "2020-05-31"
|
||
},
|
||
previous_anchor_type: "unknown" as const,
|
||
previous_anchor_value: null
|
||
};
|
||
|
||
const selectedObjectProfitabilityMessage =
|
||
'По выбранному объекту "Четки Пост (84*117)": а сколько денег мы заработали с продажжи этих четок';
|
||
|
||
it("routes selected-object profitability wording into an item profitability intent", () => {
|
||
const result = runAddressDecomposeStage(selectedObjectProfitabilityMessage, followupContext);
|
||
|
||
expect(result).not.toBeNull();
|
||
expect(result?.intent.intent).toBe("inventory_profitability_for_item");
|
||
expect(result?.intent.intent).not.toBe("customer_revenue_and_payments");
|
||
expect(result?.filters.extracted_filters.item).toBe("Четки Пост (84*117)");
|
||
expect(result?.filters.extracted_filters.period_from).toBe("2020-05-01");
|
||
expect(result?.filters.extracted_filters.period_to).toBe("2020-05-31");
|
||
});
|
||
|
||
it("answers selected-object profitability with a bounded document spread instead of a recipe gap", async () => {
|
||
executeAddressMcpQueryMock.mockResolvedValueOnce({
|
||
fetched_rows: 2,
|
||
matched_rows: 2,
|
||
raw_rows: [
|
||
{
|
||
Period: "2020-05-10T00:00:00Z",
|
||
Registrator: "Поступление товаров и услуг 000000001 от 10.05.2020",
|
||
AccountDt: "41.01",
|
||
AccountKt: "60.01",
|
||
Amount: 500,
|
||
Quantity: 10,
|
||
SubcontoDt1: "Четки Пост (84*117)",
|
||
SubcontoDt3: "Основной склад",
|
||
Counterparty: "ООО \\Поставщик\\",
|
||
Organization: "ООО \\Альтернатива Плюс\\"
|
||
},
|
||
{
|
||
Period: "2020-05-20T00:00:00Z",
|
||
Registrator: "Реализация товаров и услуг 000000017 от 20.05.2020",
|
||
AccountDt: "62.01",
|
||
AccountKt: "41.01",
|
||
Amount: 900,
|
||
Quantity: 10,
|
||
SubcontoKt1: "Четки Пост (84*117)",
|
||
SubcontoKt3: "Основной склад",
|
||
Counterparty: "ИП Покупатель",
|
||
Organization: "ООО \\Альтернатива Плюс\\"
|
||
}
|
||
],
|
||
rows: [],
|
||
error: null
|
||
});
|
||
|
||
const service = new AddressQueryService();
|
||
const result = await service.tryHandle(selectedObjectProfitabilityMessage, {
|
||
followupContext
|
||
});
|
||
|
||
expect(result?.handled).toBe(true);
|
||
expect(result?.response_type).toBe("FACTUAL_SUMMARY");
|
||
expect(result?.debug.detected_intent).toBe("inventory_profitability_for_item");
|
||
expect(result?.debug.selected_recipe).toBe("address_inventory_profitability_for_item_v1");
|
||
expect(result?.debug.capability_id).toBe("inventory_inventory_profitability_for_item");
|
||
expect(result?.debug.mcp_call_status).toBe("matched_non_empty");
|
||
expect(result?.debug.extracted_filters?.item).toBe("Четки Пост (84*117)");
|
||
const reply = String(result?.reply_text ?? "");
|
||
expect(reply).toContain("Четки Пост (84*117)");
|
||
expect(reply).toContain("900");
|
||
expect(reply).toContain("500");
|
||
expect(reply).toContain("400");
|
||
expect(reply).toContain("Маржинальность");
|
||
expect(reply).toContain("не чистая прибыль компании");
|
||
expect(executeAddressMcpQueryMock).toHaveBeenCalledTimes(1);
|
||
});
|
||
});
|