feat: image variants per image

This commit is contained in:
fsylvain committed 2026-10-08 19:57:51 +02:00
1 parent f567866161
commit 951fef18ba
92 files changed
+8695 -413

No files matched your search

+31 -2
View File
@@ -8,8 +8,11 @@ import (
domain "RenewCMS/internal/domain/image"
"RenewCMS/internal/domain/user"
"RenewCMS/internal/infrastructure/config"
"RenewCMS/internal/infrastructure/hashing"
"RenewCMS/internal/infrastructure/useCases"
"bytes"
"encoding/json"
"log"
"net/http"
"net/http/httptest"
"strings"
@@ -42,6 +45,9 @@ type variantEnv struct {
storage *mockVariantStorage
renderer *countingRenderer
audit *activityHarness
articles *mockArticleRepo
keys *mockAPIKeyRepo
logs *bytes.Buffer
token *jwtauth.JWTAuth
now time.Time
admin http.Handler
@@ -70,6 +76,9 @@ func newVariantEnvLimits(t *testing.T, renderer *countingRenderer, limits useCas
storage: newMockVariantStorage(),
renderer: renderer,
audit: newActivityHarness(t),
articles: newMockArticleRepo(),
keys: newMockAPIKeyRepo(),
logs: &bytes.Buffer{},
token: jwtauth.New("HS256", []byte("test-secret"), nil),
now: time.Date(2026, time.October, 8, 9, 0, 0, 0, time.UTC),
}
@@ -94,22 +103,42 @@ func newVariantEnvLimits(t *testing.T, renderer *countingRenderer, limits useCas
func (e *variantEnv) container(limits useCases.ServeVariantLimits) *api.UseCases {
clock := func() time.Time { return e.now }
recorder := e.audit.recorder
serve := useCases.NewServeVariantUseCase(e.variants, e.files, e.images, e.storage, e.renderer, limits)
return &api.UseCases{
Token: e.token,
GetUserUseCase: useCases.NewGetUserUseCase(e.users),
OpenMediaUseCase: useCases.NewOpenMediaUseCase(e.storage),
DeleteMediaUseCase: useCases.NewDeleteMediaUseCase(e.images, e.storage, e.files, recorder),
MergeMediaUseCase: useCases.NewMergeMediaUseCase(e.images, newMockArticleRepo(), e.storage, e.files, recorder),
MergeMediaUseCase: useCases.NewMergeMediaUseCase(e.images, e.articles, e.storage, e.files, recorder),
ListVariantsUseCase: useCases.NewListVariantsUseCase(e.variants, e.files),
CreateVariantUseCase: useCases.NewCreateVariantUseCase(e.variants, e.renderer, clock, recorder),
UpdateVariantUseCase: useCases.NewUpdateVariantUseCase(e.variants, e.files, e.storage, e.renderer, clock, recorder),
SetVariantEnabledUseCase: useCases.NewSetVariantEnabledUseCase(e.variants, e.files, clock, recorder),
DeleteVariantUseCase: useCases.NewDeleteVariantUseCase(e.variants, e.files, e.storage, recorder),
PurgeVariantUseCase: useCases.NewPurgeVariantUseCase(e.variants, e.files, e.storage, recorder),
ServeVariantUseCase: useCases.NewServeVariantUseCase(e.variants, e.files, e.images, e.storage, e.renderer, limits),
ServeVariantUseCase: serve,
CreateImageUseCase: useCases.NewCreateImageUseCase(e.images, e.storage, recorder),
ListMediaUseCase: useCases.NewListMediaUseCase(e.images, e.articles, e.users, e.files),
RenameMediaUseCase: useCases.NewRenameMediaUseCase(e.images, recorder),
GetMediaUsageUseCase: useCases.NewGetMediaUsageUseCase(e.images, e.articles),
ListImageVariantsUseCase: useCases.NewListImageVariantsUseCase(e.images, e.variants, e.files, e.renderer),
GenerateImageVariantUseCase: useCases.NewGenerateImageVariantUseCase(e.images, e.variants, e.files, e.renderer, serve),
GenerateAllImageVariantsUseCase: useCases.NewGenerateAllImageVariantsUseCase(e.images, e.variants, e.files, e.renderer, serve, recorder),
PurgeImageVariantUseCase: useCases.NewPurgeImageVariantUseCase(e.images, e.variants, e.files, e.storage, recorder),
GenerateVariantsOnUploadUseCase: useCases.NewGenerateVariantsOnUploadUseCase(e.variants, serve, log.New(e.logs, "", 0)),
AuthenticateAPIKeyUseCase: useCases.NewAuthenticateAPIKeyUseCase(e.keys, hashing.NewSHA256KeyGenerator(), e.users, clock),
ListActivityUseCase: useCases.NewListActivityUseCase(e.audit.probe, e.users, e.articles, e.images, e.keys, clock),
}
}
func (e *variantEnv) issueAPIKey() string {
generator := hashing.NewSHA256KeyGenerator()
raw, prefix, hashed := generator.Generate()
e.keys.Create(apikey.APIKey{UserID: variantOwnerId, Name: "ci", Prefix: prefix, HashedKey: hashed, CreatedAt: e.now})
return raw
}
func (e *variantEnv) cookie(userId uint32, tokenVersion uint32) *http.Cookie {
e.t.Helper()
_, signed, err := e.token.Encode(map[string]any{"user_id": userId, "token_version": tokenVersion})