package processing import ( "context" "os" "testing" "time" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgxpool" ) func TestLoadV1ProcessJobItems_promotesMoreimagesWhenMainEmpty(t *testing.T) { dsn := os.Getenv("DATABASE_URL") if dsn == "" { t.Skip("DATABASE_URL not set") } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() pg, err := pgxpool.New(ctx, dsn) if err != nil { t.Fatal(err) } defer pg.Close() companyID := uuid.New() userID := uuid.New() rawID := uuid.New() jobID := uuid.New() ppID := uuid.New() gtin := "img-v1-" + companyID.String()[:8] if _, err := pg.Exec(ctx, `INSERT INTO companies (id, name) VALUES ($1, $2)`, companyID, "img-v1-test"); err != nil { t.Fatal(err) } err = pg.QueryRow(ctx, `SELECT id FROM users ORDER BY created_at DESC LIMIT 1`).Scan(&userID) if err != nil { t.Skip("no users rows available") } defer func() { _, _ = pg.Exec(context.Background(), `DELETE FROM processing_job_products WHERE job_id = $1`, jobID) _, _ = pg.Exec(context.Background(), `DELETE FROM processing_jobs WHERE id = $1`, jobID) _, _ = pg.Exec(context.Background(), `DELETE FROM processed_products WHERE company_id = $1`, companyID) _, _ = pg.Exec(context.Background(), `DELETE FROM raw_products WHERE company_id = $1`, companyID) _, _ = pg.Exec(context.Background(), `DELETE FROM companies WHERE id = $1`, companyID) }() mapped := `{"main_image":"","moreimages":"https://cdn.example.com/a.jpg,https://cdn.example.com/b.jpg","name":"Widget"}` if _, err := pg.Exec(ctx, ` INSERT INTO raw_products (id, company_id, gtin, raw_data, mapped_data, is_processed, processing_status) VALUES ($1, $2, $3, '{}'::jsonb, $4::jsonb, true, 'processed')`, rawID, companyID, gtin, mapped); err != nil { t.Fatal(err) } if _, err := pg.Exec(ctx, ` INSERT INTO processed_products ( id, company_id, product_id, name, category, description, processed_name, processed_description, raw_product_id, status, attributes, processed_attributes, field_sources ) VALUES ( $1, $2, $3, 'Widget', NULL, 'desc', 'Widget', 'desc', $4, 'needs_review', '{}'::jsonb, '{}'::jsonb, '{}'::jsonb )`, ppID, companyID, gtin, rawID); err != nil { t.Fatal(err) } if _, err := pg.Exec(ctx, ` INSERT INTO processing_jobs (id, company_id, user_id, status, processing_type, total_products, processed_products) VALUES ($1, $2, $3, 'completed', 'full', 1, 1)`, jobID, companyID, userID); err != nil { t.Fatal(err) } if _, err := pg.Exec(ctx, ` INSERT INTO processing_job_products (id, job_id, raw_product_id, processed_product_id, status) VALUES (gen_random_uuid(), $1, $2, $3, 'processed')`, jobID, rawID, ppID); err != nil { t.Fatal(err) } p := NewPipeline(pg) items, err := p.LoadV1ProcessJobItems(ctx, companyID, jobID, "full") if err != nil { t.Fatal(err) } if len(items) != 1 { t.Fatalf("items=%d want 1", len(items)) } main, _ := items[0]["main_image"].(string) if main != "https://cdn.example.com/a.jpg" { t.Fatalf("main_image=%v want promoted moreimages[0]", items[0]["main_image"]) } switch more := items[0]["more_images"].(type) { case []string: if len(more) != 1 || more[0] != "https://cdn.example.com/b.jpg" { t.Fatalf("more_images=%v", more) } default: t.Fatalf("more_images type %T = %v", items[0]["more_images"], items[0]["more_images"]) } }