121 lines
3.6 KiB
Go
121 lines
3.6 KiB
Go
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)
|
||
|
|
}
|