package memory import ( "context" "testing" "git.yeij.top/AskaEth/Cyrene_v2/services/ai-core/model" ) func TestParseExtractedMemories(t *testing.T) { tests := []struct { input string minCount int }{ {`{"content":"用户喜欢咖啡","category":"preference","priority":0.8} {"content":"用户每天跑步","category":"fact","priority":0.7}`, 2}, {`这是提取的记忆: {"content":"用户名叫张三","category":"fact","priority":0.9} {"content":"用户在北京工作","category":"fact","priority":0.85}`, 2}, {`no json here`, 0}, {``, 0}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := parseExtractedMemories(tt.input) if len(result) < tt.minCount { t.Errorf("expected >= %d memories, got %d: %+v", tt.minCount, len(result), result) } for _, m := range result { if m.Content == "" { t.Error("memory content should not be empty") } if m.Category == "" { t.Error("memory category should not be empty") } } }) } } func TestExtractorDisabled(t *testing.T) { e := NewExtractor(nil, nil) if e.enabled { t.Error("extractor should be disabled when llm is nil") } // Should not panic e.ExtractFromConversation(nil, "user-1", nil) } func TestExtractorParseEdgeCases(t *testing.T) { // Test JSON with whitespace result := parseExtractedMemories(` {"content":"test","category":"fact","priority":0.5} `) if len(result) != 1 { t.Errorf("expected 1, got %d", len(result)) } // Test empty JSON object result = parseExtractedMemories(`{}`) if len(result) != 0 { t.Errorf("expected 0 for empty object, got %d", len(result)) } // Test invalid JSON line mixed with valid result = parseExtractedMemories(`invalid {"content":"ok","category":"fact","priority":0.5} not json either`) if len(result) != 1 { t.Errorf("expected 1 valid, got %d", len(result)) } } // mockLLM implements LLMClient for testing. type mockLLM struct { response string err error } func (m *mockLLM) Chat(_ context.Context, _ []model.LLMMessage) (*model.LLMResponse, error) { if m.err != nil { return nil, m.err } return &model.LLMResponse{Content: m.response, Model: "mock"}, nil } func TestExtractorWithMockLLM(t *testing.T) { mock := &mockLLM{ response: `{"content":"用户喜欢喝咖啡","category":"preference","priority":0.8} {"content":"用户在2024年去过日本","category":"event","priority":0.9}`, } // We can't easily test the full extraction without a real DB // But verify mock LLM works resp, err := mock.Chat(nil, nil) if err != nil { t.Fatalf("mock LLM: %v", err) } memories := parseExtractedMemories(resp.Content) if len(memories) != 2 { t.Errorf("expected 2 memories, got %d", len(memories)) } }