161 lines
4.7 KiB
Go
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))
|
|
}
|