Files
RenewCMS/test/media_merge_support_test.go
T

161 lines
4.7 KiB
Go

package test
import (
"RenewCMS/internal/domain/article"
"RenewCMS/internal/domain/audit"
"RenewCMS/internal/domain/author"
"RenewCMS/internal/domain/contenttype"
"RenewCMS/internal/domain/entry"
"RenewCMS/internal/domain/image"
"RenewCMS/internal/domain/site"
"RenewCMS/internal/domain/transaction"
"RenewCMS/internal/infrastructure/useCases"
"context"
"io"
"log"
"maps"
)
type mergeSnapshotter interface {
mergeSnapshot() func()
}
func (m *mockImageRepo) mergeSnapshot() func() {
saved, nextID := maps.Clone(m.images), m.nextID
return func() { m.images, m.nextID = maps.Clone(saved), nextID }
}
func (m *mockArticleRepo) mergeSnapshot() func() {
saved := maps.Clone(m.articles)
return func() { m.articles = maps.Clone(saved) }
}
func (m *mockSiteRepo) mergeSnapshot() func() {
saved := maps.Clone(m.sites)
return func() { m.sites = maps.Clone(saved) }
}
func (m *mockAuthorRepo) mergeSnapshot() func() {
saved := maps.Clone(m.authors)
return func() { m.authors = maps.Clone(saved) }
}
func (m *mockEntryRepo) mergeSnapshot() func() {
saved := maps.Clone(m.entries)
return func() { m.entries = maps.Clone(saved) }
}
type mockMergeTransactor struct {
repos transaction.Repositories
failBegin error
failCommit error
runCalls int
committed bool
afterCommit func()
}
var _ transaction.Transactor = &mockMergeTransactor{}
func newMergeTransactor(images image.Repository, articles article.Repository, sites site.Repository, authors author.Repository, entries entry.Repository) *mockMergeTransactor {
return &mockMergeTransactor{repos: transaction.Repositories{Articles: articles, Sites: sites, Authors: authors, Entries: entries, Images: images}}
}
func (m *mockMergeTransactor) snapshots() []func() {
var restores []func()
for _, repo := range []any{m.repos.Articles, m.repos.Sites, m.repos.Authors, m.repos.Entries, m.repos.Images} {
if snapshotter, ok := repo.(mergeSnapshotter); ok {
restores = append(restores, snapshotter.mergeSnapshot())
}
}
return restores
}
func restoreAll(restores []func()) {
for _, restore := range restores {
restore()
}
}
func (m *mockMergeTransactor) Run(ctx context.Context, work func(transaction.Repositories) error) (err error) {
m.runCalls++
m.committed = false
if m.failBegin != nil {
return m.failBegin
}
restores := m.snapshots()
defer func() {
if recovered := recover(); recovered != nil {
restoreAll(restores)
panic(recovered)
}
}()
if err := work(m.repos); err != nil {
restoreAll(restores)
return err
}
if m.failCommit != nil {
restoreAll(restores)
return m.failCommit
}
m.committed = true
if m.afterCommit != nil {
m.afterCommit()
}
return nil
}
type mergeFileCall struct {
name string
committed bool
}
type mergeRecordingStorage struct {
*mockImageStorage
transactor *mockMergeTransactor
calls []mergeFileCall
failFor map[string]error
}
var _ image.Storage = &mergeRecordingStorage{}
func newMergeRecordingStorage(transactor *mockMergeTransactor) *mergeRecordingStorage {
return &mergeRecordingStorage{mockImageStorage: newMockImageStorage(), transactor: transactor, failFor: map[string]error{}}
}
func (s *mergeRecordingStorage) Delete(name string) error {
s.calls = append(s.calls, mergeFileCall{name: name, committed: s.transactor.committed})
if err, armed := s.failFor[name]; armed {
return err
}
return s.mockImageStorage.Delete(name)
}
type mergeRecordingVariantFiles struct {
*mockVariantFileRepo
transactor *mockMergeTransactor
calls []mergeFileCall
failSource map[string]error
}
var _ image.VariantFileRepository = &mergeRecordingVariantFiles{}
func newMergeRecordingVariantFiles(transactor *mockMergeTransactor) *mergeRecordingVariantFiles {
return &mergeRecordingVariantFiles{mockVariantFileRepo: newMockVariantFileRepo(), transactor: transactor, failSource: map[string]error{}}
}
func (v *mergeRecordingVariantFiles) ListBySource(sourceName string) ([]image.VariantFile, error) {
if err, armed := v.failSource[sourceName]; armed {
return nil, err
}
return v.mockVariantFileRepo.ListBySource(sourceName)
}
func (v *mergeRecordingVariantFiles) Delete(id uint32) error {
v.calls = append(v.calls, mergeFileCall{name: v.rows[id].SourceName, committed: v.transactor.committed})
return v.mockVariantFileRepo.Delete(id)
}
func newTestMergeMedia(images image.Repository, articles article.Repository, storage image.Storage, variantFiles image.VariantFileRepository, recorder audit.Recorder, sites site.Repository, authors author.Repository, types contenttype.Repository, entries entry.Repository) *useCases.MergeMediaUseCase {
return useCases.NewMergeMediaUseCase(images, articles, storage, variantFiles, recorder, types, entries, newMergeTransactor(images, articles, sites, authors, entries), log.New(io.Discard, "", 0))
}