mirror of
https://github.com/karust/openserp.git
synced 2026-08-15 21:15:56 +08:00
175 lines
6.2 KiB
Go
175 lines
6.2 KiB
Go
package core
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestEnvelopeAlwaysIncludesSerpFeatures(t *testing.T) {
|
|
env := NewEnvelope(Query{Text: "golang"}, "req-1", time.Unix(0, 0), []string{"google"})
|
|
|
|
data, err := json.Marshal(env)
|
|
if err != nil {
|
|
t.Fatalf("marshal envelope: %v", err)
|
|
}
|
|
if !strings.Contains(string(data), `"serp_features":[]`) {
|
|
t.Fatalf("expected empty serp_features array in JSON, got %s", data)
|
|
}
|
|
}
|
|
|
|
func TestAppendEnrichedSearchResultAddsFeatureSurface(t *testing.T) {
|
|
env := NewEnvelope(Query{Text: "weather"}, "req-1", time.Unix(0, 0), []string{"google"})
|
|
raw := SearchResult{
|
|
Rank: 1,
|
|
URL: "https://example.com/weather",
|
|
Title: "Weather result",
|
|
Description: "Organic snippet",
|
|
Features: []SerpFeature{{
|
|
Type: ResultTypeAnswerBox,
|
|
Text: "72 F and sunny",
|
|
Links: []FeatureLink{{
|
|
Title: "Weather source",
|
|
URL: "https://example.com/weather",
|
|
}},
|
|
Position: &Position{Absolute: 1},
|
|
Confidence: 0.9,
|
|
}},
|
|
}
|
|
|
|
AppendEnrichedSearchResult(env, raw, EnrichContext{Engine: "google", Query: Query{}}, time.Unix(0, 0))
|
|
|
|
if len(env.Results) != 1 {
|
|
t.Fatalf("expected 1 result, got %d", len(env.Results))
|
|
}
|
|
if len(env.SerpFeatures) != 1 {
|
|
t.Fatalf("expected 1 feature, got %d", len(env.SerpFeatures))
|
|
}
|
|
feature := env.SerpFeatures[0]
|
|
if feature.ID == "" || !strings.HasPrefix(feature.ID, "f_") {
|
|
t.Fatalf("expected stable feature ID, got %q", feature.ID)
|
|
}
|
|
if feature.Engine != "google" {
|
|
t.Fatalf("feature engine = %q, want google", feature.Engine)
|
|
}
|
|
if feature.ExtractedAt != "1970-01-01T00:00:00Z" {
|
|
t.Fatalf("feature extracted_at = %q", feature.ExtractedAt)
|
|
}
|
|
if len(feature.SourceResultIDs) != 1 || feature.SourceResultIDs[0] != env.Results[0].ID {
|
|
t.Fatalf("expected feature to reference result ID %q, got %#v", env.Results[0].ID, feature.SourceResultIDs)
|
|
}
|
|
}
|
|
|
|
func TestAppendEnrichedSearchResultMirrorsExistingAnswerResultAsFeature(t *testing.T) {
|
|
env := NewEnvelope(Query{Text: "weather"}, "req-1", time.Unix(0, 0), []string{"google"})
|
|
raw := SearchResult{
|
|
Rank: -1,
|
|
Type: ResultTypeAnswerBox,
|
|
URL: "https://example.com/weather",
|
|
Title: "Weather",
|
|
Description: "72 F and sunny",
|
|
}
|
|
|
|
AppendEnrichedSearchResult(env, raw, EnrichContext{Engine: "google", Query: Query{}}, time.Unix(0, 0))
|
|
|
|
if len(env.Results) != 1 {
|
|
t.Fatalf("expected existing result to be preserved, got %d results", len(env.Results))
|
|
}
|
|
if len(env.SerpFeatures) != 1 {
|
|
t.Fatalf("expected mirrored feature, got %d", len(env.SerpFeatures))
|
|
}
|
|
if env.SerpFeatures[0].Type != ResultTypeAnswerBox {
|
|
t.Fatalf("mirrored feature type = %q", env.SerpFeatures[0].Type)
|
|
}
|
|
if env.SerpFeatures[0].Text != "72 F and sunny" {
|
|
t.Fatalf("mirrored feature text = %q", env.SerpFeatures[0].Text)
|
|
}
|
|
if len(env.SerpFeatures[0].SourceResultIDs) != 1 || env.SerpFeatures[0].SourceResultIDs[0] != env.Results[0].ID {
|
|
t.Fatalf("mirrored feature did not reference result: %#v", env.SerpFeatures[0].SourceResultIDs)
|
|
}
|
|
}
|
|
|
|
func TestRenderersIncludeSerpFeatures(t *testing.T) {
|
|
env := NewEnvelope(Query{Text: "openserp"}, "req-1", time.Unix(0, 0), []string{"google"})
|
|
AppendEnrichedSearchResult(env, SearchResult{
|
|
Rank: 1,
|
|
URL: "https://example.com/result",
|
|
Title: "Organic result",
|
|
Description: "Snippet",
|
|
Features: []SerpFeature{
|
|
{
|
|
Type: ResultTypeAISummary,
|
|
Text: "OpenSERP is a search API.",
|
|
Links: []FeatureLink{{
|
|
Title: "Example",
|
|
URL: "https://example.com/source",
|
|
}},
|
|
Position: &Position{Absolute: 1},
|
|
Confidence: 0.95,
|
|
},
|
|
{
|
|
Type: ResultTypeRelatedSearches,
|
|
Items: []FeatureItem{
|
|
{Text: "openserp cloud"},
|
|
{Text: "serp api"},
|
|
},
|
|
},
|
|
},
|
|
}, EnrichContext{Engine: "google", Query: Query{}}, time.Unix(0, 0))
|
|
env.Finalize(time.Unix(0, 0), Query{Text: "openserp", Limit: 10})
|
|
|
|
markdown := string(RenderMarkdown(env))
|
|
if !strings.Contains(markdown, "## AI summary") || !strings.Contains(markdown, "Sources:") {
|
|
t.Fatalf("markdown missing AI summary feature section:\n%s", markdown)
|
|
}
|
|
if !strings.Contains(markdown, "## Results") {
|
|
t.Fatalf("markdown missing Results section:\n%s", markdown)
|
|
}
|
|
if !strings.Contains(markdown, "## Related searches") {
|
|
t.Fatalf("markdown missing related searches section:\n%s", markdown)
|
|
}
|
|
// Spec order: AI summary -> ... -> Results -> Related searches.
|
|
if aiIdx, resIdx, relIdx := strings.Index(markdown, "## AI summary"), strings.Index(markdown, "## Results"), strings.Index(markdown, "## Related searches"); !(aiIdx < resIdx && resIdx < relIdx) {
|
|
t.Fatalf("markdown section order wrong: ai=%d results=%d related=%d\n%s", aiIdx, resIdx, relIdx, markdown)
|
|
}
|
|
|
|
text := string(RenderText(env))
|
|
if !strings.Contains(text, "AI summary\n") || !strings.Contains(text, "Related searches\n") {
|
|
t.Fatalf("text missing feature sections:\n%s", text)
|
|
}
|
|
|
|
lines := strings.Split(strings.TrimSpace(string(RenderNDJSON(env))), "\n")
|
|
if len(lines) != 3 {
|
|
t.Fatalf("expected 3 ndjson lines, got %d: %v", len(lines), lines)
|
|
}
|
|
if !strings.Contains(lines[0], `"kind":"result"`) {
|
|
t.Fatalf("first ndjson line should be a result, got %s", lines[0])
|
|
}
|
|
if !strings.Contains(lines[1], `"kind":"feature"`) || !strings.Contains(lines[2], `"kind":"feature"`) {
|
|
t.Fatalf("feature ndjson lines missing kind tag: %v", lines)
|
|
}
|
|
}
|
|
|
|
// TestRenderFeaturesUnorderedTypeStillRenders guards against silently dropping a
|
|
// feature whose Type is in neither render-order section (e.g. a newly added
|
|
// enum value not yet placed). It must still appear in text and markdown output.
|
|
func TestRenderFeaturesUnorderedTypeStillRenders(t *testing.T) {
|
|
const unplaced ResultType = "experimental_module"
|
|
env := NewEnvelope(Query{Text: "openserp"}, "req-1", time.Unix(0, 0), []string{"google"})
|
|
env.SerpFeatures = append(env.SerpFeatures, SerpFeature{
|
|
Type: unplaced,
|
|
Text: "experimental feature body",
|
|
})
|
|
|
|
text := string(RenderText(env))
|
|
if !strings.Contains(text, "experimental feature body") {
|
|
t.Fatalf("text output dropped an unordered feature type:\n%s", text)
|
|
}
|
|
|
|
markdown := string(RenderMarkdown(env))
|
|
if !strings.Contains(markdown, "experimental feature body") {
|
|
t.Fatalf("markdown output dropped an unordered feature type:\n%s", markdown)
|
|
}
|
|
}
|