Files
mailarchiv/audit_test.go
T
2026-03-12 16:27:28 +01:00

147 lines
4.1 KiB
Go

package audit_test
import (
"path/filepath"
"testing"
"time"
"log/slog"
"os"
"github.com/mailarchive/internal/audit"
)
func newTestAudit(t *testing.T) *audit.Logger {
t.Helper()
dir := t.TempDir()
logger := slog.New(slog.NewTextHandler(os.Discard, nil))
l, err := audit.New(filepath.Join(dir, "audit.db"), dir, logger)
if err != nil {
t.Fatalf("audit.New: %v", err)
}
t.Cleanup(func() { l.Close() })
return l
}
func TestLogAndQuery(t *testing.T) {
l := newTestAudit(t)
l.Log(audit.Entry{
EventType: audit.EventLogin,
Username: "alice",
IPAddress: "192.168.1.1",
Success: true,
})
l.Log(audit.Entry{
EventType: audit.EventSearch,
Username: "alice",
IPAddress: "192.168.1.1",
Query: "invoice",
Success: true,
})
l.Log(audit.Entry{
EventType: audit.EventLogin,
Username: "bob",
IPAddress: "10.0.0.1",
Success: false,
Detail: "wrong password",
})
all, total, err := l.Query(audit.QueryFilter{PageSize: 50})
if err != nil {
t.Fatalf("Query all: %v", err)
}
if total != 3 {
t.Errorf("expected 3 entries, got %d", total)
}
_ = all
}
func TestQueryByUsername(t *testing.T) {
l := newTestAudit(t)
l.Log(audit.Entry{EventType: audit.EventLogin, Username: "alice", Success: true})
l.Log(audit.Entry{EventType: audit.EventSearch, Username: "alice", Success: true})
l.Log(audit.Entry{EventType: audit.EventLogin, Username: "bob", Success: true})
entries, total, _ := l.Query(audit.QueryFilter{Username: "alice", PageSize: 50})
if total != 2 {
t.Errorf("alice: expected 2 entries, got %d", total)
}
for _, e := range entries {
if e.Username != "alice" {
t.Errorf("got entry for user %q in alice filter", e.Username)
}
}
}
func TestQueryByEventType(t *testing.T) {
l := newTestAudit(t)
l.Log(audit.Entry{EventType: audit.EventLogin, Username: "alice", Success: true})
l.Log(audit.Entry{EventType: audit.EventSearch, Username: "alice", Success: true})
l.Log(audit.Entry{EventType: audit.EventMailView, Username: "alice", MailID: "abc123", Success: true})
_, total, _ := l.Query(audit.QueryFilter{EventType: audit.EventSearch, PageSize: 50})
if total != 1 {
t.Errorf("search event filter: expected 1, got %d", total)
}
}
func TestQueryByMailID(t *testing.T) {
l := newTestAudit(t)
l.Log(audit.Entry{EventType: audit.EventMailView, Username: "alice", MailID: "mail-001", Success: true})
l.Log(audit.Entry{EventType: audit.EventMailView, Username: "bob", MailID: "mail-001", Success: true})
l.Log(audit.Entry{EventType: audit.EventMailView, Username: "alice", MailID: "mail-002", Success: true})
_, total, _ := l.Query(audit.QueryFilter{MailID: "mail-001", PageSize: 50})
if total != 2 {
t.Errorf("mailID filter: expected 2, got %d", total)
}
}
func TestQueryDateRange(t *testing.T) {
l := newTestAudit(t)
l.Log(audit.Entry{EventType: audit.EventLogin, Username: "alice", Success: true})
l.Log(audit.Entry{EventType: audit.EventLogin, Username: "bob", Success: true})
// Query with future date range — should return 0
future := time.Now().Add(24 * time.Hour)
futureEnd := time.Now().Add(48 * time.Hour)
_, total, _ := l.Query(audit.QueryFilter{From: &future, To: &futureEnd, PageSize: 50})
if total != 0 {
t.Errorf("future date range should return 0, got %d", total)
}
// Query with past-to-now range — should return all
past := time.Now().Add(-1 * time.Minute)
now := time.Now().Add(1 * time.Minute)
_, total, _ = l.Query(audit.QueryFilter{From: &past, To: &now, PageSize: 50})
if total != 2 {
t.Errorf("current date range should return 2, got %d", total)
}
}
func TestQueryPagination(t *testing.T) {
l := newTestAudit(t)
for i := 0; i < 10; i++ {
l.Log(audit.Entry{EventType: audit.EventSearch, Username: "alice", Success: true})
}
page0, total, _ := l.Query(audit.QueryFilter{PageSize: 4, Page: 0})
_, _, _ = l.Query(audit.QueryFilter{PageSize: 4, Page: 1})
page2, _, _ := l.Query(audit.QueryFilter{PageSize: 4, Page: 2})
if total != 10 {
t.Errorf("total = %d, want 10", total)
}
if len(page0) != 4 {
t.Errorf("page 0 len = %d, want 4", len(page0))
}
if len(page2) != 2 {
t.Errorf("page 2 len = %d, want 2", len(page2))
}
}