package test import ( domain "RenewCMS/internal/domain/image" persistence "RenewCMS/internal/infrastructure/persistence/repositories" "errors" "testing" "time" ) func persistedVariant(name string, width *int, height *int) domain.Variant { quality := 80 return domain.Variant{Name: name, Width: width, Height: height, Fit: domain.FitCover, Format: domain.FormatJPEG, Quality: &quality, Enabled: true} } func intPointer(value int) *int { return &value } func TestVariantRepository(t *testing.T) { t.Run("A created variant is read back with absent dimensions as nil", func(t *testing.T) { repo := persistence.NewVariantRepository(openActivityDatabase(t)) if _, err := repo.Create(persistedVariant("card", intPointer(800), nil)); err != nil { t.Fatal(err) } stored, err := repo.Get("card") if err != nil || stored.Width == nil || *stored.Width != 800 || stored.Height != nil || *stored.Quality != 80 || !stored.Enabled { t.Errorf("stored = %+v, err = %v", stored, err) } }) t.Run("A png variant keeps a nil quality and a disabled variant stays disabled", func(t *testing.T) { repo := persistence.NewVariantRepository(openActivityDatabase(t)) logo := persistedVariant("logo", intPointer(100), nil) logo.Format, logo.Quality, logo.Enabled = domain.FormatPNG, nil, false if _, err := repo.Create(logo); err != nil { t.Fatal(err) } stored, _ := repo.Get("logo") if stored.Quality != nil || stored.Enabled || stored.GenerateOnUpload { t.Errorf("stored = %+v", stored) } }) t.Run("A duplicate name is refused with ErrVariantExists", func(t *testing.T) { repo := persistence.NewVariantRepository(openActivityDatabase(t)) _, _ = repo.Create(persistedVariant("thumb", intPointer(400), nil)) _, err := repo.Create(persistedVariant("thumb", intPointer(800), nil)) if !errors.Is(err, domain.ErrVariantExists) { t.Errorf("err = %v", err) } }) t.Run("The list is ordered by name", func(t *testing.T) { repo := persistence.NewVariantRepository(openActivityDatabase(t)) for _, name := range []string{"hero", "card", "thumb"} { _, _ = repo.Create(persistedVariant(name, intPointer(100), nil)) } listed, err := repo.List() if err != nil || len(listed) != 3 || listed[0].Name != "card" || listed[1].Name != "hero" || listed[2].Name != "thumb" { t.Errorf("listed = %+v, err = %v", listed, err) } }) t.Run("An update replaces the rendering settings and nulls a removed dimension", func(t *testing.T) { repo := persistence.NewVariantRepository(openActivityDatabase(t)) _, _ = repo.Create(persistedVariant("hero", intPointer(1200), intPointer(630))) changed := persistedVariant("hero", intPointer(1000), nil) changed.UpdatedAt = time.Date(2026, 10, 8, 9, 0, 0, 0, time.UTC) if _, err := repo.Update(changed); err != nil { t.Fatal(err) } stored, _ := repo.Get("hero") if *stored.Width != 1000 || stored.Height != nil || !stored.UpdatedAt.Equal(changed.UpdatedAt) { t.Errorf("stored = %+v", stored) } }) t.Run("An unknown variant is reported as ErrVariantNotFound on get, update and delete", func(t *testing.T) { repo := persistence.NewVariantRepository(openActivityDatabase(t)) _, getErr := repo.Get("missing") _, updateErr := repo.Update(persistedVariant("missing", intPointer(1), nil)) deleteErr := repo.Delete("missing") for _, err := range []error{getErr, updateErr, deleteErr} { if !errors.Is(err, domain.ErrVariantNotFound) { t.Errorf("err = %v", err) } } }) t.Run("A deleted variant is gone", func(t *testing.T) { repo := persistence.NewVariantRepository(openActivityDatabase(t)) _, _ = repo.Create(persistedVariant("hero", intPointer(100), nil)) if err := repo.Delete("hero"); err != nil { t.Fatal(err) } if _, err := repo.Get("hero"); !errors.Is(err, domain.ErrVariantNotFound) { t.Errorf("err = %v", err) } }) } func TestVariantFileRepository(t *testing.T) { file := func(variant string, source string, cached string, size int64) domain.VariantFile { return domain.VariantFile{VariantName: variant, SourceName: source, CachedName: cached, ContentType: "image/jpeg", Size: size, Fingerprint: "f1"} } t.Run("A saved file is found by variant and source", func(t *testing.T) { repo := persistence.NewVariantFileRepository(openActivityDatabase(t)) _, _ = repo.Save(file("hero", "a.png", "g1.jpeg", 1000)) found, ok, err := repo.Find("hero", "a.png") if err != nil || !ok || found.CachedName != "g1.jpeg" || found.Size != 1000 || found.Fingerprint != "f1" || found.ContentType != "image/jpeg" || found.ID == 0 { t.Errorf("found = %+v, ok = %v, err = %v", found, ok, err) } }) t.Run("Finding nothing is not an error", func(t *testing.T) { repo := persistence.NewVariantFileRepository(openActivityDatabase(t)) _, ok, err := repo.Find("hero", "a.png") if ok || err != nil { t.Errorf("ok = %v, err = %v", ok, err) } }) t.Run("Saving again for the same variant and source replaces the row", func(t *testing.T) { repo := persistence.NewVariantFileRepository(openActivityDatabase(t)) _, _ = repo.Save(file("hero", "a.png", "g1.jpeg", 1000)) if _, err := repo.Save(file("hero", "a.png", "g2.jpeg", 500)); err != nil { t.Fatal(err) } rows, _ := repo.ListByVariant("hero") if len(rows) != 1 || rows[0].CachedName != "g2.jpeg" || rows[0].Size != 500 { t.Errorf("rows = %+v", rows) } }) t.Run("Rows are listed by variant and by source", func(t *testing.T) { repo := persistence.NewVariantFileRepository(openActivityDatabase(t)) _, _ = repo.Save(file("hero", "a.png", "g1.jpeg", 1)) _, _ = repo.Save(file("hero", "b.png", "g2.jpeg", 2)) _, _ = repo.Save(file("thumb", "a.png", "g3.jpeg", 3)) byVariant, _ := repo.ListByVariant("hero") bySource, _ := repo.ListBySource("a.png") if len(byVariant) != 2 || len(bySource) != 2 { t.Errorf("by variant = %+v, by source = %+v", byVariant, bySource) } }) t.Run("Totals count files and bytes per variant", func(t *testing.T) { repo := persistence.NewVariantFileRepository(openActivityDatabase(t)) _, _ = repo.Save(file("hero", "a.png", "g1.jpeg", 1000)) _, _ = repo.Save(file("hero", "b.png", "g2.jpeg", 2000)) _, _ = repo.Save(file("hero", "c.png", "g3.jpeg", 3000)) totals, err := repo.Totals() if err != nil || totals["hero"].Files != 3 || totals["hero"].Bytes != 6000 || len(totals) != 1 { t.Errorf("totals = %+v, err = %v", totals, err) } }) t.Run("Deleting a row removes only that row and tolerates a missing one", func(t *testing.T) { repo := persistence.NewVariantFileRepository(openActivityDatabase(t)) first, _ := repo.Save(file("hero", "a.png", "g1.jpeg", 1)) _, _ = repo.Save(file("hero", "b.png", "g2.jpeg", 2)) firstErr := repo.Delete(first.ID) secondErr := repo.Delete(first.ID) rows, _ := repo.ListByVariant("hero") if firstErr != nil || secondErr != nil || len(rows) != 1 { t.Errorf("rows = %+v, errs = %v %v", rows, firstErr, secondErr) } }) }