153 lines
6.1 KiB
Go
153 lines
6.1 KiB
Go
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"
|
|
)
|
|
|
|
// A categorised product with no formula of its own enhances through the English
|
|
// platform default rather than the generic "1-3 paragraphs" rule.
|
|
func TestWithDefaultCategoryFormula_appliesToCategorisedProduct(t *testing.T) {
|
|
t.Parallel()
|
|
got := withDefaultCategoryFormula(ProductInput{
|
|
CategoryUniqueID: "high-chairs",
|
|
CategoryDisplayName: "High chairs",
|
|
})
|
|
if got.CategoryEnhancePrompt == "" {
|
|
t.Fatal("expected the platform default overlay")
|
|
}
|
|
if FormatTitleFormulaConstraint(got.TitleTemplate) == "" {
|
|
t.Fatalf("expected a default title formula, got %#v", got.TitleTemplate)
|
|
}
|
|
if FormatDescriptionFormulaConstraint(got.DescriptionTemplate) == "" {
|
|
t.Fatalf("expected a default description formula, got %#v", got.DescriptionTemplate)
|
|
}
|
|
}
|
|
|
|
func TestWithDefaultCategoryFormula_doesNotOverride(t *testing.T) {
|
|
t.Parallel()
|
|
cases := map[string]ProductInput{
|
|
"no category at all": {},
|
|
"category prompt already set": {
|
|
CategoryUniqueID: "high-chairs",
|
|
CategoryEnhancePrompt: "--- Title ---\nKeep the supplier title.\n--- End Title ---",
|
|
},
|
|
"tenant-authored enhance template": {
|
|
CategoryUniqueID: "high-chairs",
|
|
EnhanceUserTemplate: "Write a haiku about {{name}}",
|
|
},
|
|
"category has its own title formula": {
|
|
CategoryUniqueID: "high-chairs",
|
|
TitleTemplate: map[string]any{"separator": " ", "elements": []any{
|
|
map[string]any{"type": "variable", "value": "product_type"},
|
|
map[string]any{"type": "variable", "value": "brand"},
|
|
}},
|
|
},
|
|
}
|
|
for name, in := range cases {
|
|
t.Run(name, func(t *testing.T) {
|
|
got := withDefaultCategoryFormula(in)
|
|
if got.CategoryEnhancePrompt != in.CategoryEnhancePrompt {
|
|
t.Fatalf("platform default overrode an explicit choice: %q", got.CategoryEnhancePrompt)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// A1's Slovenian formulas keep the Slovenian scaffolding and system prompt they had
|
|
// in generator.php; the English defaults get an English frame. Output language is
|
|
// set by {{language}} in both cases.
|
|
func TestResolveProductPromptTemplates_scaffoldingFollowsFormulaLanguage(t *testing.T) {
|
|
t.Parallel()
|
|
slovenian := aiprompts.SplitLegacyCombinedEnhancePrompt(a1StolckiLegacyPrompt)
|
|
sysSL, userSL := resolveProductPromptTemplates(ProductInput{
|
|
CategoryUniqueID: "stolcki",
|
|
CategoryDisplayName: "Stolčki",
|
|
CategoryEnhancePrompt: slovenian,
|
|
Language: "sl",
|
|
})
|
|
if !strings.Contains(sysSL, "Si tekstopisec") {
|
|
t.Fatalf("Slovenian formula must keep the Slovenian system prompt:\n%s", sysSL)
|
|
}
|
|
for _, want := range []string{"GPT predloga:", "Staro_ime_izdelka: {{name}}", "<name>{"} {
|
|
if !strings.Contains(userSL, want) {
|
|
t.Fatalf("Slovenian scaffolding missing %q:\n%s", want, userSL)
|
|
}
|
|
}
|
|
|
|
sysEN, userEN := resolveProductPromptTemplates(ProductInput{
|
|
CategoryUniqueID: "high-chairs",
|
|
CategoryDisplayName: "High chairs",
|
|
})
|
|
if !strings.Contains(sysEN, "You are a copywriter") {
|
|
t.Fatalf("English default must use the English system prompt:\n%s", sysEN)
|
|
}
|
|
for _, want := range []string{"Product template:", "Old_product_name: {{name}}", "<name>{"} {
|
|
if !strings.Contains(userEN, want) {
|
|
t.Fatalf("English scaffolding missing %q:\n%s", want, userEN)
|
|
}
|
|
}
|
|
if strings.Contains(userEN, "GPT predloga") || strings.Contains(userEN, "Staro_ime_izdelka") {
|
|
t.Fatalf("English default leaked Slovenian scaffolding:\n%s", userEN)
|
|
}
|
|
}
|
|
|
|
// End to end through RunSteps: a category with no stored formula still produces
|
|
// formula-shaped HTML and a rebuilt name, and the feed is only used as evidence.
|
|
func TestRunSteps_defaultFormulaDrivesGeneration(t *testing.T) {
|
|
t.Parallel()
|
|
reply, _ := json.Marshal(map[string]any{
|
|
"name": "BRUNNER folding chair ONE SHOT 0404164N.C20",
|
|
"description": "<h2>BRUNNER folding chair for life on the road</h2><p>" +
|
|
strings.Repeat("A light aluminium frame opens in one motion and stays steady on uneven ground. ", 4) +
|
|
"</p><h2>Built to last a season outdoors</h2><p>" +
|
|
strings.Repeat("Reinforced joints take the load where it matters and wipe clean in seconds. ", 4) +
|
|
"</p><b>Technical specifications</b><ul><li>Brand: BRUNNER</li><li>Material: aluminium</li></ul>",
|
|
"attrs": map[string]any{"brand": "BRUNNER", "product_model": "ONE SHOT 0404164N.C20"},
|
|
})
|
|
c := &formulaRegressionCompleter{reply: string(reply)}
|
|
feedName := "BRUNNER folding camping chair ONE SHOT grey black 0404164N.C20"
|
|
feedDesc := "An elegant and very light chair designed for art directors. Folding aluminium frame and armrests."
|
|
|
|
out, err := (&Engine{Completer: c}).RunSteps(context.Background(), "co", ProductInput{
|
|
GTIN: "8022068075495",
|
|
Name: feedName,
|
|
Description: feedDesc,
|
|
Mapped: map[string]any{
|
|
"name": feedName, "description": feedDesc,
|
|
"brand": "BRUNNER", "category": "high-chairs",
|
|
"specifications": map[string]any{"Material": "aluminium"},
|
|
},
|
|
Language: "en",
|
|
ContentLanguages: []string{"en"},
|
|
CategoryNamesByUID: map[string]string{"high-chairs": "High chairs"},
|
|
}, "full", []string{"high-chairs"}, StepPolicy{AllowAI: true})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if c.calls != 1 {
|
|
t.Fatalf("a compliant reply must not need a retry, calls=%d", c.calls)
|
|
}
|
|
if !strings.Contains(c.user, "Product template:") || !strings.Contains(c.user, "<H2>{") {
|
|
t.Fatalf("default formula never reached the prompt:\n%s", c.user)
|
|
}
|
|
if out.ProcessedName == out.Name || out.ProcessedDescription == out.Description {
|
|
t.Fatal("enriched output must differ from the feed")
|
|
}
|
|
if !strings.Contains(out.ProcessedDescription, "<h2>") || !strings.Contains(out.ProcessedDescription, "<ul>") {
|
|
t.Fatalf("processed description is not formula HTML: %q", out.ProcessedDescription)
|
|
}
|
|
if out.Name != feedName || out.Description != feedDesc {
|
|
t.Fatalf("Original must stay the feed: name=%q desc=%q", out.Name, out.Description)
|
|
}
|
|
if h, _ := out.FieldSources[FieldEnhanceInputHash].(string); h == "" {
|
|
t.Fatal("quality enhance under the default formula must persist a hash")
|
|
}
|
|
_ = company.DefaultLanguage
|
|
}
|