109 lines
3.6 KiB
Go
109 lines
3.6 KiB
Go
package test
|
|
|
|
import (
|
|
"RenewCMS/internal/domain/audit"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestActivityRecorder(t *testing.T) {
|
|
t.Run("A failing repository does not fail the caller and the failure is logged", func(t *testing.T) {
|
|
h := newActivityHarness(t)
|
|
h.probe.appendErr = errDiskFull
|
|
|
|
h.recorder.Record(testCtx, activityValidEvent())
|
|
|
|
logs := h.logs.String()
|
|
if !strings.Contains(logs, "audit.test") || !strings.Contains(logs, "disk full") {
|
|
t.Errorf("expected a log line naming the write and the error, got %q", logs)
|
|
}
|
|
})
|
|
|
|
t.Run("A panicking repository does not crash the caller", func(t *testing.T) {
|
|
h := newActivityHarness(t)
|
|
h.probe.appendPanic = true
|
|
|
|
h.recorder.Record(testCtx, activityValidEvent())
|
|
|
|
if !strings.Contains(h.logs.String(), "panicked") {
|
|
t.Errorf("expected the panic to be logged, got %q", h.logs.String())
|
|
}
|
|
})
|
|
|
|
t.Run("The recorder fills the event from the audit context", func(t *testing.T) {
|
|
h := newActivityHarness(t)
|
|
h.now = time.Date(2026, time.October, 6, 14, 0, 0, 0, time.FixedZone("CEST", 2*3600))
|
|
ctx := audit.WithOrigin(testCtx, audit.Origin{
|
|
Actor: audit.Actor{Type: audit.ActorUser, ID: activityPtr(uint32(3)), Name: "marta"},
|
|
Source: audit.SourceWeb,
|
|
IP: "203.0.113.12",
|
|
UserAgent: "Mozilla/5.0 test",
|
|
})
|
|
event := audit.NewEvent("audit.test", audit.CategorySystem)
|
|
|
|
h.recorder.Record(ctx, event)
|
|
|
|
stored := h.all(t)
|
|
if len(stored) != 1 {
|
|
t.Fatalf("expected one event, got %d", len(stored))
|
|
}
|
|
got := stored[0]
|
|
if got.Actor.Type != audit.ActorUser || *got.Actor.ID != 3 || got.Actor.Name != "marta" || got.Source != audit.SourceWeb {
|
|
t.Errorf("unexpected actor or source %+v", got)
|
|
}
|
|
if got.IP == nil || *got.IP != "203.0.113.12" || got.UserAgent == nil || *got.UserAgent != "Mozilla/5.0 test" {
|
|
t.Errorf("unexpected ip or user agent %v %v", got.IP, got.UserAgent)
|
|
}
|
|
if !got.CreatedAt.Equal(h.now) || got.CreatedAt.Location() != time.UTC {
|
|
t.Errorf("expected created_at %v in UTC, got %v", h.now.UTC(), got.CreatedAt)
|
|
}
|
|
})
|
|
|
|
t.Run("Values already on the event are kept", func(t *testing.T) {
|
|
h := newActivityHarness(t)
|
|
ctx := audit.WithOrigin(testCtx, audit.Origin{Actor: audit.AnonymousActor("x"), Source: audit.SourceWeb, IP: "203.0.113.12", UserAgent: "ua"})
|
|
event := audit.NewEvent(audit.ActionCleanup, audit.CategorySystem)
|
|
event.Actor = audit.SystemActor()
|
|
event.Source = audit.SourceSystem
|
|
|
|
h.recorder.Record(ctx, event)
|
|
|
|
got := h.all(t)[0]
|
|
if got.Actor.Type != audit.ActorSystem || got.Source != audit.SourceSystem {
|
|
t.Errorf("the explicit actor and source must win, got %+v", got)
|
|
}
|
|
})
|
|
|
|
t.Run("An event outside the vocabulary is dropped and logged", func(t *testing.T) {
|
|
h := newActivityHarness(t)
|
|
event := activityValidEvent()
|
|
event.Category = "billing"
|
|
|
|
h.recorder.Record(testCtx, event)
|
|
|
|
if len(h.all(t)) != 0 || !strings.Contains(h.logs.String(), "dropped") {
|
|
t.Errorf("expected nothing stored and a log line, got %q", h.logs.String())
|
|
}
|
|
})
|
|
|
|
t.Run("Long names are bounded", func(t *testing.T) {
|
|
h := newActivityHarness(t)
|
|
event := activityValidEvent()
|
|
event.Target = audit.Target{Type: "article", ID: "1", Name: strings.Repeat("é", 400)}
|
|
|
|
h.recorder.Record(testCtx, event)
|
|
|
|
if got := h.all(t); len(got) != 1 || len([]rune(got[0].Target.Name)) != 255 {
|
|
t.Errorf("expected one event with a 255 character target name, got %+v", got)
|
|
}
|
|
})
|
|
}
|
|
|
|
func activityValidEvent() audit.Event {
|
|
event := audit.NewEvent("audit.test", audit.CategorySystem)
|
|
event.Actor = audit.SystemActor()
|
|
event.Source = audit.SourceSystem
|
|
return event
|
|
}
|