|
|
@@ -0,0 +1,112 @@
|
|
|
+import { describe, expect, it } from 'vitest'
|
|
|
+
|
|
|
+import {
|
|
|
+ buildPersistedAIMessageContent,
|
|
|
+ hydratePersistedReports,
|
|
|
+ normalizeReportsForPersistence
|
|
|
+} from './chatHistoryPersistence'
|
|
|
+
|
|
|
+describe('chatHistoryPersistence', () => {
|
|
|
+ it('fills report fields from _fullContent before persistence', () => {
|
|
|
+ const reports = [
|
|
|
+ {
|
|
|
+ file_index: 1,
|
|
|
+ status: 'completed',
|
|
|
+ report: {
|
|
|
+ display_name: '',
|
|
|
+ summary: '',
|
|
|
+ analysis: '',
|
|
|
+ clauses: ''
|
|
|
+ },
|
|
|
+ _fullContent: {
|
|
|
+ display_name: '桥梁施工规范.pdf',
|
|
|
+ summary: '完整摘要',
|
|
|
+ analysis: '完整分析',
|
|
|
+ clauses: '完整条款'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
+ expect(normalizeReportsForPersistence(reports)).toEqual([
|
|
|
+ expect.objectContaining({
|
|
|
+ report: {
|
|
|
+ display_name: '桥梁施工规范.pdf',
|
|
|
+ summary: '完整摘要',
|
|
|
+ analysis: '完整分析',
|
|
|
+ clauses: '完整条款'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ it('repairs persisted reports when history reloads from older incomplete content', () => {
|
|
|
+ const reports = [
|
|
|
+ {
|
|
|
+ file_index: 2,
|
|
|
+ status: 'completed',
|
|
|
+ report: {
|
|
|
+ display_name: '',
|
|
|
+ summary: '',
|
|
|
+ analysis: '',
|
|
|
+ clauses: ''
|
|
|
+ },
|
|
|
+ _fullContent: {
|
|
|
+ display_name: '混凝土养护说明.pdf',
|
|
|
+ summary: '已保存的完整摘要',
|
|
|
+ analysis: '已保存的完整分析',
|
|
|
+ clauses: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'category_title',
|
|
|
+ category: '国家规范',
|
|
|
+ number: '一',
|
|
|
+ count: 1
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
+ expect(hydratePersistedReports(reports)).toEqual([
|
|
|
+ expect.objectContaining({
|
|
|
+ report: {
|
|
|
+ display_name: '混凝土养护说明.pdf',
|
|
|
+ summary: '已保存的完整摘要',
|
|
|
+ analysis: '已保存的完整分析',
|
|
|
+ clauses: ''
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ expect.objectContaining({
|
|
|
+ type: 'category_title',
|
|
|
+ category: '国家规范'
|
|
|
+ })
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ it('builds structured content for professional replies before the stream finishes', () => {
|
|
|
+ const content = buildPersistedAIMessageContent({
|
|
|
+ reports: [],
|
|
|
+ summary: '',
|
|
|
+ _fullSummary: '已识别到专业问题,正在分析相关规范。',
|
|
|
+ webSearchRaw: null,
|
|
|
+ webSearchSummary: null,
|
|
|
+ hasWebSearchResults: false,
|
|
|
+ content: ''
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(JSON.parse(content)).toEqual({
|
|
|
+ reports: [],
|
|
|
+ webSearchRaw: null,
|
|
|
+ webSearchSummary: null,
|
|
|
+ hasWebSearchResults: false,
|
|
|
+ summary: '已识别到专业问题,正在分析相关规范。'
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('returns plain text for direct AI answers without structured report data', () => {
|
|
|
+ expect(buildPersistedAIMessageContent({
|
|
|
+ reports: [],
|
|
|
+ content: '你好,我在。',
|
|
|
+ summary: '',
|
|
|
+ _fullSummary: ''
|
|
|
+ })).toBe('你好,我在。')
|
|
|
+ })
|
|
|
+})
|