Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
package seo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAnalyze_missingMetaAndImage(t *testing.T) {
|
||||
products := []ProductInput{
|
||||
{
|
||||
ID: "p1",
|
||||
Name: "Acme UltraWidget Pro 3000 Stainless",
|
||||
Category: "Widgets",
|
||||
ProcessedAttrs: map[string]any{"brand": "Acme"},
|
||||
},
|
||||
}
|
||||
recs := Analyze(products, nil)
|
||||
types := map[string]bool{}
|
||||
for _, r := range recs {
|
||||
types[r.Type] = true
|
||||
if r.EntityID != "p1" && r.Type != TypeDuplicateTitle {
|
||||
t.Fatalf("unexpected entity %s", r.EntityID)
|
||||
}
|
||||
}
|
||||
for _, want := range []string{TypeMissingMetaTitle, TypeMissingMetaDescription, TypeMissingImage} {
|
||||
if !types[want] {
|
||||
t.Fatalf("expected type %s", want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyze_duplicateAndThin(t *testing.T) {
|
||||
products := []ProductInput{
|
||||
{ID: "a", Name: "Short", MetaTitle: "x", MetaDescription: "y"},
|
||||
{ID: "b", Name: "Short", MetaTitle: "x", MetaDescription: "y"},
|
||||
}
|
||||
recs := Analyze(products, nil)
|
||||
var thin, dup int
|
||||
for _, r := range recs {
|
||||
switch r.Type {
|
||||
case TypeThinTitle:
|
||||
thin++
|
||||
case TypeDuplicateTitle:
|
||||
dup++
|
||||
}
|
||||
}
|
||||
if thin < 2 {
|
||||
t.Fatalf("expected thin titles, got %d", thin)
|
||||
}
|
||||
if dup < 2 {
|
||||
t.Fatalf("expected duplicate titles, got %d", dup)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyze_duplicatePeerAndRecCaps(t *testing.T) {
|
||||
n := maxDupRecsPerTitle + maxPeerIDsPerDup + 10
|
||||
products := make([]ProductInput, 0, n)
|
||||
for i := 0; i < n; i++ {
|
||||
products = append(products, ProductInput{
|
||||
ID: fmt.Sprintf("p%d", i),
|
||||
Name: "Shared Title Product",
|
||||
MetaTitle: "mt",
|
||||
MetaDescription: "md",
|
||||
})
|
||||
}
|
||||
recs := Analyze(products, nil)
|
||||
var dup int
|
||||
var peerLen int
|
||||
for _, r := range recs {
|
||||
if r.Type != TypeDuplicateTitle {
|
||||
continue
|
||||
}
|
||||
dup++
|
||||
peers, _ := r.Meta["peer_ids"].([]string)
|
||||
if peerLen == 0 {
|
||||
peerLen = len(peers)
|
||||
}
|
||||
if len(peers) > maxPeerIDsPerDup {
|
||||
t.Fatalf("peer_ids len=%d want <=%d", len(peers), maxPeerIDsPerDup)
|
||||
}
|
||||
count, _ := r.Meta["duplicate_count"].(int)
|
||||
if count != n {
|
||||
t.Fatalf("duplicate_count=%d want %d", count, n)
|
||||
}
|
||||
}
|
||||
if dup != maxDupRecsPerTitle {
|
||||
t.Fatalf("duplicate recs=%d want %d", dup, maxDupRecsPerTitle)
|
||||
}
|
||||
if peerLen != maxPeerIDsPerDup {
|
||||
t.Fatalf("peer_ids len=%d want %d", peerLen, maxPeerIDsPerDup)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyze_categoryMeta(t *testing.T) {
|
||||
cats := []CategoryInput{
|
||||
{ID: "c1", UniqueID: "cat-1", Name: "AB", DescriptionTemplate: map[string]any{}},
|
||||
{ID: "c2", UniqueID: "cat-2", Name: "Appliances", DescriptionTemplate: map[string]any{
|
||||
"metaTitle": "t", "metaDescription": "d",
|
||||
}},
|
||||
}
|
||||
recs := Analyze(nil, cats)
|
||||
var missing, thin int
|
||||
for _, r := range recs {
|
||||
if r.Type == TypeCategoryMissingMeta {
|
||||
missing++
|
||||
if r.EntityID != "c1" {
|
||||
t.Fatalf("wrong category for missing meta: %s", r.EntityID)
|
||||
}
|
||||
}
|
||||
if r.Type == TypeThinCategoryName {
|
||||
thin++
|
||||
}
|
||||
}
|
||||
if missing != 1 {
|
||||
t.Fatalf("expected 1 missing meta formula, got %d", missing)
|
||||
}
|
||||
if thin != 1 {
|
||||
t.Fatalf("expected 1 thin category name, got %d", thin)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFillMetaTemplate(t *testing.T) {
|
||||
title, desc := FillMetaTemplate(ProductInput{
|
||||
Name: "Drill 18V",
|
||||
Category: "Tools",
|
||||
Description: "Cordless drill with battery pack for DIY projects.",
|
||||
Attributes: map[string]any{"brand": "Bosch"},
|
||||
})
|
||||
if title == "" || desc == "" {
|
||||
t.Fatal("expected non-empty meta")
|
||||
}
|
||||
if runeLen(title) > MetaTitleMaxChars {
|
||||
t.Fatalf("title too long: %d", runeLen(title))
|
||||
}
|
||||
if runeLen(desc) > MetaDescriptionMaxChars {
|
||||
t.Fatalf("desc too long: %d", runeLen(desc))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildChecklist_score(t *testing.T) {
|
||||
products := []ProductInput{
|
||||
{ID: "1", Name: "Good Product Title Here", MetaTitle: "mt", MetaDescription: "md",
|
||||
MappedData: map[string]any{"image_url": "https://example.com/a.jpg"}, Category: "Good Product Title Here"},
|
||||
}
|
||||
recs := Analyze(products, nil)
|
||||
checklist, overall := BuildChecklist(recs, 1, 0)
|
||||
if overall <= 0 {
|
||||
t.Fatalf("expected positive overall, got %v", overall)
|
||||
}
|
||||
if len(checklist) != len(AllTypes()) {
|
||||
t.Fatalf("checklist len %d want %d", len(checklist), len(AllTypes()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllTypesStable(t *testing.T) {
|
||||
types := AllTypes()
|
||||
if len(types) != 8 {
|
||||
t.Fatalf("want 8 types, got %d", len(types))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user