Files

121 lines
3.6 KiB
Go
Raw Permalink Normal View History

2026-08-16 23:42:00 +02:00
package processing
import (
"context"
"encoding/json"
"strings"
"testing"
)
func TestAttrsFromEnhanceObj_andMerge(t *testing.T) {
t.Parallel()
obj := map[string]any{
"name": "Monitor",
"attrs": map[string]any{
"diagonala_zaslona": "27\"",
"zavora": "junk",
"brand": "Acme",
},
}
got := attrsFromEnhanceObj(obj)
if got["brand"] != "Acme" || got["diagonala_zaslona"] != "27\"" {
t.Fatalf("attrsFromEnhanceObj=%v", got)
}
allowed := map[string]struct{}{
"diagonala_zaslona": {},
"vrsta_panela": {},
}
merged := mergeEnhanceAttrsInto(map[string]any{
"brand": "Acme",
"product_model": "X1",
}, got, allowed)
if merged["diagonala_zaslona"] != "27\"" {
t.Fatalf("expected remapped/validated diagonala, got %v", merged)
}
if _, ok := merged["zavora"]; ok {
t.Fatalf("zavora must be dropped by allowlist: %v", merged)
}
if merged["brand"] != "Acme" || merged["product_model"] != "X1" {
t.Fatalf("core/base attrs must remain: %v", merged)
}
if mergeEnhanceAttrsInto(map[string]any{"a": 1}, nil, allowed) != nil {
t.Fatal("empty llm attrs must yield nil (no change)")
}
}
func TestEnhanceAttrsFromRaw_roundTrip(t *testing.T) {
t.Parallel()
meta := map[string]any{"status": "ok"}
attachEnhanceAttrs(meta, map[string]any{"brand": "Bosch", "nosilnost": "40 kg"})
got := enhanceAttrsFromRaw(meta)
if got["brand"] != "Bosch" || got["nosilnost"] != "40 kg" {
t.Fatalf("round-trip attrs=%v", got)
}
}
func TestRunSteps_enhanceMergesValidatedAttrs(t *testing.T) {
t.Parallel()
payload := mustJSON(map[string]any{
"name": "Acme UltraView 27",
"description": "<h2>Acme UltraView 27</h2><p>27 inch IPS monitor for desk work with clear specs.</p><ul><li>27 inch</li><li>IPS panel</li></ul>",
"meta_title": "Acme UltraView 27 | IPS",
"meta_description": "Shop Acme UltraView 27 IPS monitor.",
"attrs": map[string]any{
"diagonala_zaslona": "27\"",
"vrsta_panela": "IPS",
"zavora": "must-drop",
},
})
e := &Engine{
Completer: stubCompleter{fn: func(system, user string) (Completion, error) {
return Completion{Text: payload, TotalTokens: 12, Raw: map[string]any{"ok": true}}, nil
}},
Vector: NoopVectorCategorizer{},
}
out, err := e.RunSteps(context.Background(), "co", ProductInput{
Name: "UltraView 27 Gaming Monitor",
Description: "A solid IPS desk monitor with factory specs.",
Mapped: map[string]any{
"category_unique_id": "28",
"name": "UltraView 27 Gaming Monitor",
"attributes": map[string]any{
"brand": "Acme",
},
},
CategoryNamesByUID: map[string]string{"28": "Monitorji"},
CategoryUniqueID: "28",
CategoryAttrKeys: map[string]map[string]struct{}{
"28": {"diagonala_zaslona": {}, "vrsta_panela": {}},
},
CategoryEnhancePrompt: "Focus on panel technology for monitors.",
Language: "en",
}, "full", nil, StepPolicy{AllowAI: true})
if err != nil {
t.Fatal(err)
}
pa := out.ProcessedAttributes
if pa["diagonala_zaslona"] != "27\"" || pa["vrsta_panela"] != "IPS" {
t.Fatalf("expected LLM attrs merged: %v notes=%v gpt=%v", pa, out.Notes, out.GPTResponse)
}
if _, ok := pa["zavora"]; ok {
t.Fatalf("zavora must not survive allowlist: %v", pa)
}
if pa["brand"] != "Acme" {
t.Fatalf("feed brand must remain: %v", pa)
}
if out.FieldSources["attributes"] != "ai_enhance" {
t.Fatalf("field source=%v", out.FieldSources["attributes"])
}
if !strings.Contains(out.ProcessedName, "UltraView") {
t.Fatalf("name=%q", out.ProcessedName)
}
}
func mustJSON(v any) string {
b, err := json.Marshal(v)
if err != nil {
panic(err)
}
return string(b)
}