package processing
import (
"encoding/json"
"strings"
"testing"
"github.com/google/uuid"
)
func TestParseV1ProcessingTypeFullAndSteps(t *testing.T) {
storage, resp, err := ParseV1ProcessingType(nil)
if err != nil || storage != "full" || resp != "full" {
t.Fatalf("nil: storage=%q resp=%v err=%v", storage, resp, err)
}
storage, resp, err = ParseV1ProcessingType("title")
if err != nil || storage != "title" || resp != "title" {
t.Fatalf("title: storage=%q resp=%v err=%v", storage, resp, err)
}
storage, _, err = ParseV1ProcessingType("normalize_only")
if err != nil || storage != "normalize_only" {
t.Fatalf("normalize_only: storage=%q err=%v", storage, err)
}
storage, resp, err = ParseV1ProcessingType([]any{"title", "attributes"})
if err != nil || storage != `["title","attributes"]` {
t.Fatalf("array: storage=%q resp=%v err=%v", storage, resp, err)
}
arr, ok := resp.([]string)
if !ok || len(arr) != 2 {
t.Fatalf("resp=%v", resp)
}
_, _, err = ParseV1ProcessingType("nope")
if err == nil {
t.Fatal("expected invalid type error")
}
}
func TestMapJobStatusForV1(t *testing.T) {
if got := MapJobStatusForV1("pending"); got != "PENDING" {
t.Fatalf("got %q", got)
}
if got := MapJobStatusForV1("running"); got != "PROCESSING" {
t.Fatalf("got %q", got)
}
if got := MapJobStatusForV1("completed"); got != "COMPLETED" {
t.Fatalf("got %q", got)
}
for _, syn := range []string{"success", "done", "finished", "processed"} {
if got := MapJobStatusForV1(syn); got != "COMPLETED" {
t.Fatalf("%s -> %q", syn, got)
}
}
if !JobStatusIncludesProducts("completed") || JobStatusIncludesProducts("running") {
t.Fatal("JobStatusIncludesProducts mismatch")
}
}
func TestMapV1JobItemStatus(t *testing.T) {
if got := MapV1JobItemStatus("processed", true); got != "processed" {
t.Fatalf("got %q", got)
}
if got := MapV1JobItemStatus("failed", false); got != "failed" {
t.Fatalf("got %q", got)
}
if got := MapV1JobItemStatus("", false); got != "not_found" {
t.Fatalf("got %q", got)
}
if got := MapV1JobItemStatus("", true); got != "processed" {
t.Fatalf("got %q", got)
}
}
func TestProjectV1ProcessJobItemsPartial(t *testing.T) {
items := []V1ProcessJobItem{{
"ean": "123", "status": "processed",
"name": "T", "meta_title": "MT",
"description": "D", "attributes": map[string]any{"brand": "X"},
"main_image": "https://example.com/a.jpg", "more_images": []string{"https://example.com/b.jpg"},
"eprel": nil, "category": "cat", "category_name": "Cat",
}}
out := ProjectV1ProcessJobItems("title", items)
if len(out) != 1 {
t.Fatalf("len=%d", len(out))
}
raw, _ := json.Marshal(out[0])
var got map[string]any
_ = json.Unmarshal(raw, &got)
if got["name"] != "T" || got["ean"] != "123" {
t.Fatalf("got=%v", got)
}
if _, ok := got["title"]; ok {
t.Fatalf("duplicate title should be omitted when name exists: %v", got)
}
if _, ok := got["attributes"]; ok {
t.Fatalf("attributes should be projected out: %v", got)
}
if got["main_image"] != "https://example.com/a.jpg" {
t.Fatalf("images always included: %v", got)
}
if got["status"] != "processed" {
t.Fatalf("status should be preserved: %v", got)
}
for _, junk := range []string{"id", "processed_product_id", "raw_product_id"} {
if _, ok := got[junk]; ok {
t.Fatalf("%s must be omitted from V1 process items: %v", junk, got)
}
}
}
func TestProjectV1ProcessJobItemsTitleDerivesName(t *testing.T) {
items := []V1ProcessJobItem{{
"ean": "123", "status": "processed", "title": "OnlyTitle", "meta_title": "MT",
}}
out := ProjectV1ProcessJobItems("title", items)
if len(out) != 1 {
t.Fatalf("len=%d", len(out))
}
if out[0]["name"] != "OnlyTitle" {
t.Fatalf("name should derive from title when absent: %v", out[0]["name"])
}
if _, ok := out[0]["title"]; ok {
t.Fatalf("title omitted when identical to name: %v", out[0])
}
}
func TestV1PlainDescriptionStandalone(t *testing.T) {
got := v1PlainDescription("Line1
Line2 & ok")
if strings.Contains(got, "<") {
t.Fatalf("html left: %q", got)
}
if !strings.Contains(got, "Line1") || !strings.Contains(got, "Line2") || !strings.Contains(got, "& ok") {
t.Fatalf("got=%q", got)
}
}
func TestV1PlainDescriptionEdgeCases(t *testing.T) {
nbsp := "\u00a0"
cases := []struct {
name string
in string
want string
}{
{name: "empty", in: "", want: ""},
{name: "whitespace", in: " \n\t ", want: ""},
{name: "plain", in: "Hello world", want: "Hello world"},
{name: "html_br", in: "Hello
World
& more