fix
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
package processing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/aiprompts"
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/company"
|
||||
)
|
||||
|
||||
// Regression: enhance used to stamp processed_* onto name/description, so Review
|
||||
// always showed Matched — and formula invent ("Ključne lastnosti") overwrote the
|
||||
// feed Original. Original must stay supplier; enriched must change.
|
||||
func TestRunSteps_enhancePreservesOriginalVsEnriched(t *testing.T) {
|
||||
t.Parallel()
|
||||
prompt := aiprompts.SectionTitleStart + "\n" +
|
||||
`Napiši novo ime izdelka po formuli: tip znamka model barva.` + "\n" +
|
||||
aiprompts.SectionTitleEnd + "\n\n" +
|
||||
aiprompts.SectionDescriptionStart + "\n" +
|
||||
`<H2>{Naslov}</H2><p>{Odstavek}</p><ul><li>{Spec}</li></ul>` + "\n" +
|
||||
aiprompts.SectionDescriptionEnd
|
||||
|
||||
feedName := "BRUNNER zložljiv stol za kampiranje ONE SHOT 0404164N.C20"
|
||||
feedDesc := "Predstavljajte si eleganten in izjemno lahek stol, zasnovan posebej za umetniške direktorje."
|
||||
newName := "zložljiv stol Brunner ONE SHOT siv"
|
||||
newDesc := "<h2>Lahek kamp stol</h2><p>" + strings.Repeat("Udobje na poti. ", 15) +
|
||||
"</p><ul><li>width: 0.44m</li><li>weight: 2.88kg</li></ul>"
|
||||
|
||||
reply, _ := json.Marshal(map[string]any{
|
||||
"name": newName,
|
||||
"description": newDesc,
|
||||
"meta_title": newName,
|
||||
"meta_description": "Brunner ONE SHOT zložljiv kamp stol",
|
||||
"attrs": map[string]any{"brand": "BRUNNER"},
|
||||
})
|
||||
e := &Engine{
|
||||
Completer: stubCompleter{fn: func(_, _ string) (Completion, error) {
|
||||
return Completion{Text: string(reply), TotalTokens: 20, Model: "mock"}, nil
|
||||
}},
|
||||
Vector: NoopVectorCategorizer{},
|
||||
}
|
||||
descTpl := aiprompts.EffectiveDescriptionTemplateAny(nil, prompt)
|
||||
out, err := e.RunSteps(context.Background(), "co-preserve", ProductInput{
|
||||
GTIN: "8022068075495",
|
||||
Name: feedName,
|
||||
Description: feedDesc,
|
||||
Mapped: map[string]any{"name": feedName, "description": feedDesc, "brand": "BRUNNER", "category": "stolcki"},
|
||||
Language: "sl",
|
||||
CategoryEnhancePrompt: prompt,
|
||||
DescriptionTemplate: descTpl,
|
||||
CategoryNamesByUID: map[string]string{"stolcki": "Stolčki"},
|
||||
CategoryUniqueID: "stolcki",
|
||||
PriorCategory: "stolcki",
|
||||
}, "enhance_only", nil, StepPolicy{AllowAI: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if out.Name != feedName {
|
||||
t.Fatalf("Original name must stay feed, got %q", out.Name)
|
||||
}
|
||||
if out.Description != feedDesc {
|
||||
t.Fatalf("Original description must stay feed, got %q", out.Description)
|
||||
}
|
||||
if out.ProcessedName != newName {
|
||||
t.Fatalf("ProcessedName=%q want %q", out.ProcessedName, newName)
|
||||
}
|
||||
if !strings.Contains(out.ProcessedDescription, "<h2>") {
|
||||
t.Fatalf("ProcessedDescription missing formula HTML: %s", out.ProcessedDescription)
|
||||
}
|
||||
if out.ProcessedName == out.Name {
|
||||
t.Fatal("Review must show name Changed (enriched ≠ original)")
|
||||
}
|
||||
if out.ProcessedDescription == out.Description {
|
||||
t.Fatal("Review must show description Changed (enriched ≠ original)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunSteps_formulaInventDoesNotOverwriteOriginal(t *testing.T) {
|
||||
t.Parallel()
|
||||
prompt := aiprompts.SectionDescriptionStart + "\n" +
|
||||
`<H2>{Naslov}</H2><p>{Odstavek}</p><ul><li>{Spec}</li></ul>` + "\n" +
|
||||
aiprompts.SectionDescriptionEnd
|
||||
feedName := "BRUNNER ONE SHOT"
|
||||
feedDesc := "Predstavljajte si eleganten in izjemno lahek stol za umetniške direktorje."
|
||||
// Completer echoes supplier — formula gate synthesizes processed HTML.
|
||||
reply, _ := json.Marshal(map[string]any{
|
||||
"name": feedName,
|
||||
"description": feedDesc,
|
||||
})
|
||||
e := &Engine{
|
||||
Completer: stubCompleter{fn: func(_, _ string) (Completion, error) {
|
||||
return Completion{Text: string(reply), TotalTokens: 8, Model: "mock"}, nil
|
||||
}},
|
||||
Vector: NoopVectorCategorizer{},
|
||||
}
|
||||
descTpl := aiprompts.EffectiveDescriptionTemplateAny(nil, prompt)
|
||||
out, err := e.RunSteps(context.Background(), "co-invent", ProductInput{
|
||||
Name: feedName,
|
||||
Description: feedDesc,
|
||||
Mapped: map[string]any{"name": feedName, "description": feedDesc, "brand": "BRUNNER", "width": "0.44m"},
|
||||
Language: "sl",
|
||||
CategoryEnhancePrompt: prompt,
|
||||
DescriptionTemplate: descTpl,
|
||||
}, "enhance_only", nil, StepPolicy{AllowAI: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if out.Description != feedDesc {
|
||||
t.Fatalf("invent must not overwrite Original description, got %q", out.Description)
|
||||
}
|
||||
if !strings.Contains(strings.ToLower(out.ProcessedDescription), "ključne lastnosti") &&
|
||||
!company.LooksLikeHeuristicSynthesize(out.ProcessedDescription) &&
|
||||
!descriptionSatisfiesFormula(out.ProcessedDescription, descTpl) {
|
||||
t.Fatalf("expected processed formula/synth HTML, got %q", out.ProcessedDescription)
|
||||
}
|
||||
if out.ProcessedDescription == out.Description {
|
||||
t.Fatal("Original and Enriched must differ when invent fills processed only")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnhanceHashForceReason_descCopyPaste(t *testing.T) {
|
||||
t.Parallel()
|
||||
long := "Supplier copy about the widget with enough characters to clear the weak-description floor for hash skip checks."
|
||||
in := ProductInput{
|
||||
Name: "Widget Pro Retail Title",
|
||||
Description: long,
|
||||
PriorProcessedName: "Widget Pro Retail Title Enriched",
|
||||
PriorProcessedDescription: long,
|
||||
DescriptionTemplate: map[string]any{
|
||||
"sections": []any{
|
||||
map[string]any{"type": "h2", "instructions": "x"},
|
||||
map[string]any{"type": "p", "instructions": "y"},
|
||||
},
|
||||
},
|
||||
}
|
||||
if got := enhanceHashForceReason(in); got != "formula-mismatch" {
|
||||
t.Fatalf("got %q want formula-mismatch", got)
|
||||
}
|
||||
in.PriorProcessedDescription = "<h2>A</h2><p>" + long + "</p>"
|
||||
in.Description = "<h2>A</h2><p>" + long + "</p>"
|
||||
if got := enhanceHashForceReason(in); got != "desc-copy-paste" {
|
||||
t.Fatalf("got %q want desc-copy-paste", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user