feat: activity log backend foundation
This commit is contained in:
1 parent
8907bb49fe
commit
50b1649965
74 files changed
+5949
-239
No files matched your search
@@ -0,0 +1,140 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/audit"
|
||||
"RenewCMS/internal/infrastructure/auditing"
|
||||
persistence "RenewCMS/internal/infrastructure/persistence/repositories"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var testCtx = context.Background()
|
||||
|
||||
var discardRecorder audit.Recorder = audit.Discard
|
||||
|
||||
type activityProbeRepo struct {
|
||||
inner audit.Repository
|
||||
appendErr error
|
||||
appendPanic bool
|
||||
reads int
|
||||
listCalls []audit.Filter
|
||||
deleteErr error
|
||||
deleteCalls int
|
||||
readErr error
|
||||
}
|
||||
|
||||
var _ audit.Repository = &activityProbeRepo{}
|
||||
|
||||
func (p *activityProbeRepo) Append(event audit.Event) (audit.Event, error) {
|
||||
if p.appendPanic {
|
||||
panic("audit repository exploded")
|
||||
}
|
||||
if p.appendErr != nil {
|
||||
return audit.Event{}, p.appendErr
|
||||
}
|
||||
return p.inner.Append(event)
|
||||
}
|
||||
|
||||
func (p *activityProbeRepo) List(filter audit.Filter) (audit.Page, error) {
|
||||
p.reads++
|
||||
p.listCalls = append(p.listCalls, filter)
|
||||
if p.readErr != nil {
|
||||
return audit.Page{}, p.readErr
|
||||
}
|
||||
return p.inner.List(filter)
|
||||
}
|
||||
|
||||
func (p *activityProbeRepo) Summary(query audit.SummaryQuery) (audit.Summary, error) {
|
||||
p.reads++
|
||||
if p.readErr != nil {
|
||||
return audit.Summary{}, p.readErr
|
||||
}
|
||||
return p.inner.Summary(query)
|
||||
}
|
||||
|
||||
func (p *activityProbeRepo) DeleteOlderThan(cutoff time.Time) (int, error) {
|
||||
p.deleteCalls++
|
||||
if p.deleteErr != nil {
|
||||
return 0, p.deleteErr
|
||||
}
|
||||
return p.inner.DeleteOlderThan(cutoff)
|
||||
}
|
||||
|
||||
type activitySettingsFake struct {
|
||||
settings audit.Settings
|
||||
saveErr error
|
||||
retentionOK int
|
||||
cleanupOK int
|
||||
}
|
||||
|
||||
var _ audit.SettingsRepository = &activitySettingsFake{}
|
||||
|
||||
func newActivitySettingsFake() *activitySettingsFake {
|
||||
return &activitySettingsFake{settings: audit.DefaultSettings()}
|
||||
}
|
||||
|
||||
func (f *activitySettingsFake) Get() (audit.Settings, error) { return f.settings, nil }
|
||||
|
||||
func (f *activitySettingsFake) SaveRetention(days int) error {
|
||||
if f.saveErr != nil {
|
||||
return f.saveErr
|
||||
}
|
||||
f.retentionOK++
|
||||
f.settings.RetentionDays = days
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *activitySettingsFake) SaveLastCleanup(at time.Time, removed int) error {
|
||||
if f.saveErr != nil {
|
||||
return f.saveErr
|
||||
}
|
||||
f.cleanupOK++
|
||||
f.settings.LastCleanupAt = &at
|
||||
f.settings.LastCleanupRemoved = removed
|
||||
return nil
|
||||
}
|
||||
|
||||
type activityHarness struct {
|
||||
probe *activityProbeRepo
|
||||
store *persistence.AuditEventRepository
|
||||
settings *activitySettingsFake
|
||||
logs *bytes.Buffer
|
||||
now time.Time
|
||||
recorder *auditing.Recorder
|
||||
}
|
||||
|
||||
func newActivityHarness(t *testing.T) *activityHarness {
|
||||
t.Helper()
|
||||
store := persistence.NewAuditEventRepository(openActivityDatabase(t))
|
||||
h := &activityHarness{
|
||||
probe: &activityProbeRepo{inner: store},
|
||||
store: store,
|
||||
settings: newActivitySettingsFake(),
|
||||
logs: &bytes.Buffer{},
|
||||
now: time.Date(2026, time.October, 6, 12, 0, 0, 0, time.UTC),
|
||||
}
|
||||
h.recorder = auditing.NewRecorder(h.probe, func() time.Time { return h.now }, log.New(h.logs, "", 0))
|
||||
return h
|
||||
}
|
||||
|
||||
func (h *activityHarness) clock() time.Time { return h.now }
|
||||
|
||||
func (h *activityHarness) all(t *testing.T) []audit.Event {
|
||||
t.Helper()
|
||||
page, err := h.store.List(audit.Filter{Page: 1, Size: 1000})
|
||||
if err != nil {
|
||||
t.Fatalf("listing stored events failed: %v", err)
|
||||
}
|
||||
return page.Items
|
||||
}
|
||||
|
||||
func (h *activityHarness) seed(t *testing.T, event audit.Event) audit.Event {
|
||||
t.Helper()
|
||||
return activityMustAppend(t, h.store, event)
|
||||
}
|
||||
|
||||
var errDiskFull = errors.New("disk full")
|
||||
Reference in new issue
Block a user