Files
RenewCMS/test/image_variants_per_image_domain_test.go

139 lines
5.8 KiB
Go

package test
import (
domain "RenewCMS/internal/domain/image"
persistence "RenewCMS/internal/infrastructure/persistence/repositories"
"errors"
"strings"
"testing"
)
func TestOutputGeometry(t *testing.T) {
width := func(value int) *int { return &value }
rows := []struct {
name string
sw, sh int
settings domain.VariantSettings
wantW, wantH int
}{
{"cover with one side", 4032, 3024, domain.VariantSettings{Width: width(800), Fit: domain.FitCover}, 800, 600},
{"cover with both sides keeps the box ratio", 4032, 3024, domain.VariantSettings{Width: width(1000), Height: width(1000), Fit: domain.FitCover}, 1000, 1000},
{"cover shrinks the box to fit the source", 300, 200, domain.VariantSettings{Width: width(400), Height: width(300), Fit: domain.FitCover}, 267, 200},
{"contain is the box", 300, 200, domain.VariantSettings{Width: width(400), Height: width(300), Fit: domain.FitContain}, 400, 300},
{"inside never upscales", 300, 200, domain.VariantSettings{Width: width(1200), Height: width(1200), Fit: domain.FitInside}, 300, 200},
{"inside keeps the source ratio", 4032, 3024, domain.VariantSettings{Width: width(1000), Height: width(1000), Fit: domain.FitInside}, 1000, 750},
{"height only", 4032, 3024, domain.VariantSettings{Height: width(2400), Fit: domain.FitInside}, 3200, 2400},
{"unknown source size", 0, 0, domain.VariantSettings{Width: width(10), Fit: domain.FitCover}, 0, 0},
}
for _, row := range rows {
t.Run(row.name, func(t *testing.T) {
gotW, gotH := domain.OutputSize(row.sw, row.sh, row.settings)
if gotW != row.wantW || gotH != row.wantH {
t.Errorf("size = %d x %d, want %d x %d", gotW, gotH, row.wantW, row.wantH)
}
})
}
}
func TestOutputFormat(t *testing.T) {
all := []domain.VariantFormat{domain.FormatOriginal, domain.FormatJPEG, domain.FormatPNG, domain.FormatWebP}
withoutWebP := []domain.VariantFormat{domain.FormatOriginal, domain.FormatJPEG, domain.FormatPNG}
rows := []struct {
format domain.VariantFormat
contentType string
encodable []domain.VariantFormat
want domain.VariantFormat
}{
{domain.FormatOriginal, "image/jpeg", all, domain.FormatJPEG},
{domain.FormatOriginal, "image/png", all, domain.FormatPNG},
{domain.FormatOriginal, "image/webp", all, domain.FormatWebP},
{domain.FormatOriginal, "image/webp", withoutWebP, domain.FormatPNG},
{domain.FormatOriginal, "image/gif", all, domain.FormatPNG},
{domain.FormatWebP, "image/jpeg", withoutWebP, domain.FormatPNG},
{domain.FormatJPEG, "image/png", all, domain.FormatJPEG},
}
for _, row := range rows {
if got := domain.OutputFormat(row.format, row.contentType, row.encodable); got != row.want {
t.Errorf("%s over %s = %s, want %s", row.format, row.contentType, got, row.want)
}
}
}
func TestMediaListQueryVariants(t *testing.T) {
t.Run("The variants filter and the total_size sort are valid", func(t *testing.T) {
query := domain.NewListQuery()
query.Variants, query.Sort = domain.VariantsWith, domain.SortTotalSize
if err := query.Validate(); err != nil {
t.Errorf("err = %v", err)
}
})
t.Run("Any other variants filter is invalid", func(t *testing.T) {
query := domain.NewListQuery()
query.Variants = "bogus"
if err := query.Validate(); !errors.Is(err, domain.ErrInvalidQuery) {
t.Errorf("err = %v", err)
}
})
}
func TestVariantFileRepositoryTotalsBySource(t *testing.T) {
repo := persistence.NewVariantFileRepository(openActivityDatabase(t))
save := func(variant string, source string, size int64) {
_, _ = repo.Save(domain.VariantFile{VariantName: variant, SourceName: source, CachedName: variant + source, ContentType: "image/jpeg", Size: size, Fingerprint: "f"})
}
save("hero", "a.png", 1000)
save("thumb", "a.png", 500)
save("hero", "b.png", 2000)
totals, err := repo.TotalsBySource()
if err != nil || len(totals) != 2 || totals["a.png"].Files != 2 || totals["a.png"].Bytes != 1500 || totals["b.png"].Files != 1 || totals["b.png"].Bytes != 2000 {
t.Errorf("totals = %+v, err = %v", totals, err)
}
}
func TestPerImageVariantLayering(t *testing.T) {
t.Run("The new use cases import no persistence, mailer, models, gorm, net/http, chi or api package", func(t *testing.T) {
forbidden := []string{"persistence", "mailer", "models", "gorm", "net/http", "go-chi", "RenewCMS/api"}
files := []string{"ListImageVariants.go", "GenerateImageVariant.go", "GenerateAllImageVariants.go", "PurgeImageVariant.go", "GenerateVariantsOnUpload.go", "ServeVariantGenerate.go", "imageVariantView.go", "ListMedia.go"}
for _, name := range files {
for _, path := range importsOf(t, "internal/infrastructure/useCases/"+name) {
for _, fragment := range forbidden {
if strings.Contains(path, fragment) {
t.Errorf("%s imports %s", name, path)
}
}
}
}
})
t.Run("The media handler imports no persistence, mailer, models or gorm package", func(t *testing.T) {
for _, file := range []string{"api/handlers/media/mediaHandler.go", "api/handlers/media/variantsHandler.go"} {
for _, path := range importsOf(t, file) {
for _, fragment := range []string{"persistence", "mailer", "models", "gorm"} {
if strings.Contains(path, fragment) {
t.Errorf("%s imports %s", file, path)
}
}
}
}
})
t.Run("Only api/dependecyInjection.go constructs the new use cases", func(t *testing.T) {
composition := readRepositoryFile(t, "api/dependecyInjection.go")
for _, constructor := range []string{"NewListImageVariantsUseCase(", "NewGenerateImageVariantUseCase(", "NewGenerateAllImageVariantsUseCase(", "NewPurgeImageVariantUseCase(", "NewGenerateVariantsOnUploadUseCase("} {
if !strings.Contains(composition, constructor) {
t.Errorf("%s is not wired in the composition root", constructor)
}
if strings.Contains(readRepositoryFile(t, "api/router.go"), constructor) {
t.Errorf("api/router.go constructs %s", constructor)
}
}
})
}