package server import ( "encoding/json" "testing" "git.wntrmute.dev/mc/mcr/internal/db" ) func TestAdminListAuditEvents(t *testing.T) { database := openAdminTestDB(t) router, _ := buildAdminRouter(t, database) // Seed some audit events. if err := database.WriteAuditEvent("login_ok", "user-1", "", "", "10.0.0.1", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } if err := database.WriteAuditEvent("manifest_pushed", "user-1", "myapp", "sha256:abc", "10.0.0.1", map[string]string{"tag": "latest"}); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } if err := database.WriteAuditEvent("login_ok", "user-2", "", "", "10.0.0.2", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } rr := adminReq(t, router, "GET", "/v1/audit", "") if rr.Code != 200 { t.Fatalf("status: got %d, want 200", rr.Code) } var events []db.AuditEvent if err := json.NewDecoder(rr.Body).Decode(&events); err != nil { t.Fatalf("decode: %v", err) } if len(events) != 3 { t.Fatalf("event count: got %d, want 3", len(events)) } } func TestAdminListAuditEventsWithFilter(t *testing.T) { database := openAdminTestDB(t) router, _ := buildAdminRouter(t, database) if err := database.WriteAuditEvent("login_ok", "user-1", "", "", "", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } if err := database.WriteAuditEvent("manifest_pushed", "user-1", "myapp", "", "", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } if err := database.WriteAuditEvent("login_ok", "user-2", "", "", "", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } // Filter by event_type. rr := adminReq(t, router, "GET", "/v1/audit?event_type=login_ok", "") if rr.Code != 200 { t.Fatalf("status: got %d, want 200", rr.Code) } var events []db.AuditEvent if err := json.NewDecoder(rr.Body).Decode(&events); err != nil { t.Fatalf("decode: %v", err) } if len(events) != 2 { t.Fatalf("event count: got %d, want 2", len(events)) } for _, e := range events { if e.EventType != "login_ok" { t.Fatalf("unexpected event type: %q", e.EventType) } } } func TestAdminListAuditEventsFilterByActor(t *testing.T) { database := openAdminTestDB(t) router, _ := buildAdminRouter(t, database) if err := database.WriteAuditEvent("login_ok", "actor-a", "", "", "", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } if err := database.WriteAuditEvent("login_ok", "actor-b", "", "", "", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } rr := adminReq(t, router, "GET", "/v1/audit?actor_id=actor-a", "") if rr.Code != 200 { t.Fatalf("status: got %d, want 200", rr.Code) } var events []db.AuditEvent if err := json.NewDecoder(rr.Body).Decode(&events); err != nil { t.Fatalf("decode: %v", err) } if len(events) != 1 { t.Fatalf("event count: got %d, want 1", len(events)) } if events[0].ActorID != "actor-a" { t.Fatalf("actor_id: got %q, want %q", events[0].ActorID, "actor-a") } } func TestAdminListAuditEventsPagination(t *testing.T) { database := openAdminTestDB(t) router, _ := buildAdminRouter(t, database) for range 5 { if err := database.WriteAuditEvent("login_ok", "user-1", "", "", "", nil); err != nil { t.Fatalf("WriteAuditEvent: %v", err) } } rr := adminReq(t, router, "GET", "/v1/audit?n=2&offset=0", "") if rr.Code != 200 { t.Fatalf("status: got %d, want 200", rr.Code) } var events []db.AuditEvent if err := json.NewDecoder(rr.Body).Decode(&events); err != nil { t.Fatalf("decode: %v", err) } if len(events) != 2 { t.Fatalf("event count: got %d, want 2", len(events)) } } func TestAdminListAuditEventsEmpty(t *testing.T) { database := openAdminTestDB(t) router, _ := buildAdminRouter(t, database) rr := adminReq(t, router, "GET", "/v1/audit", "") if rr.Code != 200 { t.Fatalf("status: got %d, want 200", rr.Code) } var events []db.AuditEvent if err := json.NewDecoder(rr.Body).Decode(&events); err != nil { t.Fatalf("decode: %v", err) } if len(events) != 0 { t.Fatalf("event count: got %d, want 0", len(events)) } } func TestAdminListAuditEventsNonAdmin(t *testing.T) { database := openAdminTestDB(t) router := buildNonAdminRouter(t, database) rr := adminReq(t, router, "GET", "/v1/audit", "") if rr.Code != 403 { t.Fatalf("status: got %d, want 403", rr.Code) } }