retrieval-inspector.test.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import { fireEvent, render, screen } from "@testing-library/react";
  2. import { describe, expect, it, vi } from "vitest";
  3. import { Inspector } from "@/components/inspector/Inspector";
  4. import { retrievalActivityItem, retrievalAgentItem } from "@/lib/layout";
  5. import type { RetrievalActivity, RetrievalAgentRun } from "@/lib/types";
  6. const queryActivity: RetrievalActivity = {
  7. id: "event:4607",
  8. kind: "query",
  9. label: "毛驴效应 心理学科普",
  10. status: "hit",
  11. resultCount: 2,
  12. detailRef: "event:4607",
  13. };
  14. function agentRun(): RetrievalAgentRun {
  15. return {
  16. id: "retrieval-agent:4601",
  17. kind: "retrieval-agent",
  18. eventId: 4601,
  19. agentType: "retrieve_data_decode_case",
  20. businessLabel: "解构 Case Agent",
  21. taskPreview: "查找毛驴效应案例",
  22. status: "completed",
  23. querySummary: { total: 1, hit: 1, empty: 0, failure: 0, unknown: 0 },
  24. attempts: [],
  25. screening: { state: "available", preview: "初筛完成" },
  26. detailRef: "retrieval-agent:4601",
  27. };
  28. }
  29. describe("retrieval Inspector", () => {
  30. it("lists agent queries and delegates same-drawer navigation", () => {
  31. const onNavigate = vi.fn();
  32. render(<Inspector
  33. item={retrievalAgentItem(agentRun(), 1, 2)}
  34. tab="business"
  35. onTab={vi.fn()}
  36. onClose={vi.fn()}
  37. onNavigate={onNavigate}
  38. detail={{
  39. detailKind: "retrieval-agent",
  40. retrievalKind: "agent",
  41. businessSections: [
  42. { id: "task", title: "取数目标", content: "查找毛驴效应案例" },
  43. { id: "screening", title: "初筛整理", content: "保留两条相关案例" },
  44. ],
  45. activities: [queryActivity],
  46. technical: {},
  47. }}
  48. />);
  49. expect(screen.getByText("查询记录")).toBeInTheDocument();
  50. expect(screen.getByText("2 条")).toBeInTheDocument();
  51. fireEvent.click(screen.getByRole("button", { name: /毛驴效应 心理学科普/ }));
  52. expect(onNavigate).toHaveBeenCalledWith(queryActivity);
  53. });
  54. it("shows an explicit notice when Pattern Relation Agent has no structured records", () => {
  55. render(<Inspector
  56. item={retrievalAgentItem({ ...agentRun(), agentType: "retrieve_data_pattern_relation", businessLabel: "Pattern / Relation Agent" }, 1, 2)}
  57. tab="business"
  58. onTab={vi.fn()}
  59. onClose={vi.fn()}
  60. detail={{
  61. detailKind: "retrieval-agent",
  62. retrievalKind: "agent",
  63. activities: [],
  64. missingActivityNotice: "本次运行未保存可下钻的结构化查询记录。",
  65. technical: {},
  66. }}
  67. />);
  68. expect(screen.getByText("本次运行未保存可下钻的结构化查询记录。")).toBeInTheDocument();
  69. });
  70. it("renders hit cases with expandable complete content", () => {
  71. render(<Inspector
  72. item={retrievalActivityItem(queryActivity, 1, 2)}
  73. tab="business"
  74. onTab={vi.fn()}
  75. onClose={vi.fn()}
  76. onBack={vi.fn()}
  77. backLabel="返回解构 Case Agent"
  78. detail={{
  79. detailKind: "retrieval-event",
  80. sourceKind: "agent-query",
  81. eventId: 4607,
  82. queryConditions: [{ key: "keyword", label: "关键词", value: "毛驴效应" }],
  83. outcome: { state: "hit", count: 2, message: "查询成功,返回 2 条结果。" },
  84. items: [{
  85. id: "case-a",
  86. title: "每天心理学 · Case 1",
  87. subtitle: "case-a",
  88. meta: [{ label: "匹配分数", value: 0.7032 }],
  89. sections: [{ title: "完整解构内容", value: [{ id: "段落1", description: "完整解构原文" }] }],
  90. }],
  91. completeness: { bodyAvailable: true, truncated: false },
  92. technical: {},
  93. }}
  94. />);
  95. expect(screen.getByText("查询成功,返回 2 条结果。")).toBeInTheDocument();
  96. expect(screen.getByText("毛驴效应")).toBeInTheDocument();
  97. expect(screen.getByText("每天心理学 · Case 1")).toBeInTheDocument();
  98. expect(screen.getByText(/\"完整解构原文\"/)).toBeInTheDocument();
  99. expect(screen.getByRole("button", { name: "返回解构 Case Agent" })).toBeInTheDocument();
  100. });
  101. it("distinguishes successful empty from technical failure", () => {
  102. const item = retrievalActivityItem({ ...queryActivity, id: "event:4603", detailRef: "event:4603", status: "empty", resultCount: 0 }, 1, 2);
  103. const { rerender } = render(<Inspector item={item} tab="business" onTab={vi.fn()} onClose={vi.fn()} detail={{
  104. detailKind: "retrieval-event",
  105. sourceKind: "agent-query",
  106. outcome: { state: "empty", count: 0, message: "查询执行成功,没有匹配数据。" },
  107. queryConditions: [{ key: "account_name", label: "账号", value: "每天一点心理学" }],
  108. items: [],
  109. completeness: { bodyAvailable: true, truncated: false },
  110. technical: {},
  111. }} />);
  112. expect(screen.getByText("查询执行成功,没有匹配数据。")).toBeInTheDocument();
  113. rerender(<Inspector item={{ ...item, id: "event:4066" }} tab="business" onTab={vi.fn()} onClose={vi.fn()} detail={{
  114. detailKind: "retrieval-event",
  115. sourceKind: "agent-query",
  116. outcome: { state: "failure", message: "查询执行失败:return_field 仅支持主脉络。", errorKind: "parameter" },
  117. queryConditions: [{ key: "return_field", label: "返回内容", value: "写法" }],
  118. items: [],
  119. completeness: { bodyAvailable: true, truncated: false },
  120. technical: {},
  121. }} />);
  122. expect(screen.getByText("查询执行失败:return_field 仅支持主脉络。")).toBeInTheDocument();
  123. expect(screen.getByText("写法")).toBeInTheDocument();
  124. });
  125. });