import { describe, expect, it } from "vitest"; import { resolveAddressIntent } from "../src/services/addressIntentResolver"; import { classifyAddressQueryShape } from "../src/services/addressQueryShapeClassifier"; import { extractAddressFilters } from "../src/services/addressFilterExtractor"; import { AddressQueryService } from "../src/services/addressQueryService"; describe("address query shape classifier", () => { it("classifies explain question as deep-shape", () => { const result = classifyAddressQueryShape("Why VAT chain does not match?"); expect(result.shape).toBe("EXPLAIN_OR_REASON"); expect(result.confidence).toBe("high"); }); it("classifies aggregate lookup question", () => { const result = classifyAddressQueryShape("who owes us today?"); expect(result.shape).toBe("AGGREGATE_LOOKUP"); }); it("classifies compound factual question", () => { const result = classifyAddressQueryShape("who owes us and who we owe today?"); expect(result.shape).toBe("COMPOUND_FACTUAL_QUERY"); }); }); describe("address intent resolver expansion (M2.3a)", () => { it("resolves documents by counterparty intent", () => { const result = resolveAddressIntent("show documents by counterparty Alfa from 2020-07-01 to 2020-07-31"); expect(result.intent).toBe("list_documents_by_counterparty"); }); it("resolves bank operations by counterparty intent", () => { const result = resolveAddressIntent("show bank operations by counterparty Alfa"); expect(result.intent).toBe("bank_operations_by_counterparty"); }); it("resolves documents forming balance intent", () => { const result = resolveAddressIntent("which documents form balance for account 62 as of 2020-07-31"); expect(result.intent).toBe("documents_forming_balance"); }); }); describe("address filter extraction for balance drilldown", () => { it("defaults as_of_date for documents_forming_balance when date is omitted", () => { const result = extractAddressFilters("which documents form balance for account 62", "documents_forming_balance"); expect(result.extracted_filters.account).toBe("62"); expect(result.extracted_filters.as_of_date).toBeDefined(); expect(result.missing_required_filters).toEqual([]); }); }); describe("address query limited taxonomy and stage diagnostics", () => { it("returns missing_anchor for open items without concrete counterparty/contract anchor", async () => { const service = new AddressQueryService(); const result = await service.tryHandle("show open items by contract"); expect(result?.handled).toBe(true); expect(result?.response_type).toBe("LIMITED_WITH_REASON"); expect(result?.debug.limited_reason_category).toBe("missing_anchor"); expect(result?.debug.mcp_call_status).toBe("skipped"); }); it("returns unsupported for not-implemented contract document list intent", async () => { const service = new AddressQueryService(); const result = await service.tryHandle("show documents by contract 15/24"); expect(result?.handled).toBe(true); expect(result?.response_type).toBe("LIMITED_WITH_REASON"); expect(result?.debug.limited_reason_category).toBe("unsupported"); expect(result?.debug.mcp_call_status).toBe("skipped"); }); it("includes resolver and row-stage diagnostics", async () => { const service = new AddressQueryService(); const result = await service.tryHandle("which documents form balance for account 62 as of 2020-07-31"); expect(result?.handled).toBe(true); expect(result?.response_type).toBe("LIMITED_WITH_REASON"); expect(result?.debug.anchor_type).toBe("account"); expect(result?.debug.rows_fetched).toBeTypeOf("number"); expect(result?.debug.raw_rows_received).toBeTypeOf("number"); expect(result?.debug.rows_after_account_scope).toBeTypeOf("number"); expect(result?.debug.rows_materialized).toBeTypeOf("number"); expect(result?.debug.rows_after_recipe_filter).toBeTypeOf("number"); expect(result?.debug.rows_matched).toBeTypeOf("number"); expect(["strict", "preferred"]).toContain(result?.debug.account_scope_mode); expect(result?.debug.account_scope_fallback_applied).toBeTypeOf("boolean"); expect(result?.debug.mcp_call_status_legacy).toBeDefined(); expect(result?.debug.match_failure_stage).toBeDefined(); expect([ "no_raw_rows", "raw_rows_received_but_not_materialized", "materialized_but_not_anchor_matched", "materialized_but_filtered_out_by_recipe", "materialized_but_not_matched", "matched_non_empty" ]).toContain(result?.debug.mcp_call_status); expect(result?.debug.raw_row_keys_sample).toBeDefined(); expect(result?.debug.materialization_drop_reason).toBeDefined(); expect(result?.debug.account_scope_fields_checked).toBeDefined(); expect(result?.debug.account_scope_match_strategy).toBe("account_code_regex_plus_alias_map_v1"); expect(result?.debug.account_scope_drop_reason).toBeDefined(); }); });