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,125 @@
|
||||
package feeds
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func TestDetectMappedChangesPriceStock(t *testing.T) {
|
||||
t.Parallel()
|
||||
old := []byte(`{"price":"10","stock":"5","title":"A"}`)
|
||||
changes := detectMappedChanges(old, map[string]any{"price": "12", "stock": "5", "title": "A"})
|
||||
if len(changes) != 1 || changes[0] != "price" {
|
||||
t.Fatalf("changes=%v", changes)
|
||||
}
|
||||
changes = detectMappedChanges(old, map[string]any{"price": "10", "stock": "0", "title": "A"})
|
||||
if len(changes) != 1 || changes[0] != "stock" {
|
||||
t.Fatalf("stock changes=%v", changes)
|
||||
}
|
||||
changes = detectMappedChanges(old, map[string]any{"price": "11", "stock": "1", "title": "B", "availability": "out"})
|
||||
want := map[string]bool{"price": true, "stock": true, "title": true, "availability": true}
|
||||
for _, c := range changes {
|
||||
if !want[c] {
|
||||
t.Fatalf("unexpected %s in %v", c, changes)
|
||||
}
|
||||
delete(want, c)
|
||||
}
|
||||
if len(want) != 0 {
|
||||
t.Fatalf("missing %v from %v", want, changes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifyUpsertOpsStampsSyncChanges(t *testing.T) {
|
||||
t.Parallel()
|
||||
idUpdate := uuid.MustParse("22222222-2222-2222-2222-222222222222")
|
||||
existing := map[string]existingProduct{
|
||||
"update": {ID: idUpdate, MappedData: []byte(`{"price":"10","title":"Old"}`)},
|
||||
}
|
||||
chunk := []pendingProduct{
|
||||
{GTIN: "new", RawData: map[string]string{"EAN": "new"}, MappedData: map[string]any{"title": "N"}},
|
||||
{GTIN: "update", RawData: map[string]string{"EAN": "update"}, MappedData: map[string]any{"price": "12", "title": "Old"}},
|
||||
}
|
||||
ops, skipped := classifyUpsertOps(chunk, existing)
|
||||
if skipped != 0 || len(ops) != 2 {
|
||||
t.Fatalf("ops=%d skipped=%d", len(ops), skipped)
|
||||
}
|
||||
if ops[0].kind != upsertOpInsert || len(ops[0].changes) != 1 || ops[0].changes[0] != "new" {
|
||||
t.Fatalf("insert op=%+v", ops[0])
|
||||
}
|
||||
var mapped map[string]any
|
||||
if err := json.Unmarshal(ops[0].mappedJSON, &mapped); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tags, _ := mapped[syncChangesMappedKey].([]any)
|
||||
if len(tags) != 1 || tags[0] != "new" {
|
||||
t.Fatalf("insert mapped meta=%v", mapped[syncChangesMappedKey])
|
||||
}
|
||||
if ops[1].kind != upsertOpUpdate || len(ops[1].changes) != 1 || ops[1].changes[0] != "price" {
|
||||
t.Fatalf("update op=%+v", ops[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncDeltaCountsAddChanges(t *testing.T) {
|
||||
t.Parallel()
|
||||
var d syncDeltaCounts
|
||||
d.addChanges([]string{"price", "stock"})
|
||||
d.addChanges([]string{"new"})
|
||||
d.addChanges(nil)
|
||||
if d.PriceChanged != 1 || d.StockChanged != 1 || d.New != 1 || d.OtherChanged != 1 {
|
||||
t.Fatalf("%+v", d)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPreserveSyncedExtrasKeepsCategory(t *testing.T) {
|
||||
t.Parallel()
|
||||
existing := []byte(`{"price":"10","category":"46","title":"Roborock"}`)
|
||||
mapped := map[string]any{"price": "12", "title": "Roborock"}
|
||||
got := preserveSyncedExtras(existing, mapped)
|
||||
if got["category"] != "46" {
|
||||
t.Fatalf("category=%v want 46", got["category"])
|
||||
}
|
||||
if got["price"] != "12" {
|
||||
t.Fatalf("price=%v want 12", got["price"])
|
||||
}
|
||||
// Explicit new category wins.
|
||||
mapped2 := map[string]any{"price": "12", "category": "120"}
|
||||
got2 := preserveSyncedExtras(existing, mapped2)
|
||||
if got2["category"] != "120" {
|
||||
t.Fatalf("category=%v want 120", got2["category"])
|
||||
}
|
||||
// Empty / none prior must not invent a category.
|
||||
got3 := preserveSyncedExtras([]byte(`{"category":"none"}`), map[string]any{"title": "X"})
|
||||
if _, ok := got3["category"]; ok {
|
||||
t.Fatalf("unexpected category=%v", got3["category"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifyUpsertOpsPreservesCategory(t *testing.T) {
|
||||
t.Parallel()
|
||||
idUpdate := uuid.MustParse("33333333-3333-3333-3333-333333333333")
|
||||
existing := map[string]existingProduct{
|
||||
"keep": {ID: idUpdate, MappedData: []byte(`{"price":"10","category":"46","title":"Old"}`)},
|
||||
}
|
||||
chunk := []pendingProduct{
|
||||
{GTIN: "keep", RawData: map[string]string{"EAN": "keep"}, MappedData: map[string]any{"price": "12", "title": "Old"}},
|
||||
}
|
||||
ops, skipped := classifyUpsertOps(chunk, existing)
|
||||
if skipped != 0 || len(ops) != 1 {
|
||||
t.Fatalf("ops=%d skipped=%d", len(ops), skipped)
|
||||
}
|
||||
if ops[0].kind != upsertOpUpdate {
|
||||
t.Fatalf("kind=%v want update", ops[0].kind)
|
||||
}
|
||||
var mapped map[string]any
|
||||
if err := json.Unmarshal(ops[0].mappedJSON, &mapped); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if mapped["category"] != "46" {
|
||||
t.Fatalf("category wiped: %v", mapped["category"])
|
||||
}
|
||||
if mapped["price"] != "12" {
|
||||
t.Fatalf("price=%v", mapped["price"])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user