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( "../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("returns a truthful recipe visibility gap until item profitability gets a dedicated recipe", async () => { const service = new AddressQueryService(); const result = await service.tryHandle(selectedObjectProfitabilityMessage, { followupContext }); expect(result?.handled).toBe(true); expect(result?.response_type).toBe("LIMITED_WITH_REASON"); expect(result?.debug.detected_intent).toBe("inventory_profitability_for_item"); expect(result?.debug.selected_recipe).toBeNull(); expect(result?.debug.limited_reason_category).toBe("recipe_visibility_gap"); expect(result?.debug.extracted_filters?.item).toBe("Четки Пост (84*117)"); expect(String(result?.reply_text ?? "")).toContain("Четки Пост (84*117)"); expect(executeAddressMcpQueryMock).not.toHaveBeenCalled(); }); });