package catalog import ( "os" "path/filepath" "reflect" "testing" ) // TestRegistryLookupAndDefault — registered tenant wins, unknown falls back. func TestRegistryLookupAndDefault(t *testing.T) { r := NewRegistry() if got := r.SchemaFor("missing"); !reflect.DeepEqual(got, DefaultSchema()) { t.Errorf("unknown tenant did not fall back to DefaultSchema") } bygg := BygglagretSchema() if err := r.Register(bygg); err != nil { t.Fatalf("Register: %v", err) } got := r.SchemaFor("bygglagret") if got.SKUField != "ArticleNumber" { t.Errorf("Register did not store under Tenant: %+v", got) } if got.SKUField == DefaultSchema().SKUField { t.Errorf("Expected bygglagret to differ from default") } } // TestRegisterRejectsInvalidSchema — guard against typos in operator JSON. func TestRegisterRejectsInvalidSchema(t *testing.T) { r := NewRegistry() err := r.Register(Schema{Tenant: "broken", PriceField: "x"}) // missing SKUField if err == nil { t.Error("expected error for schema without SKUField") } err = r.Register(Schema{Tenant: "negscale", SKUField: "s", PriceField: "p", PriceScale: -1}) if err == nil { t.Error("expected error for negative PriceScale") } } // TestTenantsSorted — dashboard-friendly ordering. func TestTenantsSorted(t *testing.T) { r := NewRegistry() for _, k := range []string{"zeta", "alpha", "mu"} { s := Schema{Tenant: k, SKUField: "s", PriceField: "p"} if err := r.Register(s); err != nil { t.Fatalf("Register %s: %v", k, err) } } got := r.Tenants() want := []string{"alpha", "mu", "zeta"} if !reflect.DeepEqual(got, want) { t.Errorf("Tenants() got %v want %v", got, want) } } // TestLoadFileMissingIsOK — file is optional. func TestLoadFileMissingIsOK(t *testing.T) { r := NewRegistry() if err := r.LoadFile(filepath.Join(t.TempDir(), "nope.json")); err != nil { t.Errorf("missing file should be a no-op, got %v", err) } } // TestLoadFileHappy — load tenant schemas from disk and look one up. func TestLoadFileHappy(t *testing.T) { // JSON shape mirrors schema.go json tags; tenant keys ("bygglagret") are // the registry names. jsonBody := `{ "bygglagret": { "sku_field": "ArticleNumber", "price_field": "PriceInclVAT", "price_scale": 100, "id_prefix": "sku:", "updated_at_source": 1, "updated_at_field": "LastModifiedMs", "fixed_currency": "SEK" }, "north": { "sku_field": "sku", "price_field": "price_minor", "price_scale": 1 } }` dir := t.TempDir() path := filepath.Join(dir, "schemas.json") writeFile(t, path, jsonBody) r := NewRegistry() if err := r.LoadFile(path); err != nil { t.Fatalf("LoadFile: %v", err) } if got := r.SchemaFor("bygglagret").PriceField; got != "PriceInclVAT" { t.Errorf("bygglagret not loaded: %q", got) } if got := r.SchemaFor("north").PriceScale; got != 1 { t.Errorf("north not loaded: %d", got) } } // writeFile is a local helper; writes the JSON tenant-schema fixture to path. func writeFile(t *testing.T, path, body string) { t.Helper() if err := os.WriteFile(path, []byte(body), 0o644); err != nil { t.Fatalf("write %s: %v", path, err) } }