package services import ( "slices" "testing" ) // Pure-Go tests for the SystemView registry. Each system view's specs // must self-validate; the slugs must be reserved. func TestSystemViews_AllValidate(t *testing.T) { for _, sv := range AllSystemViews() { t.Run(sv.Slug, func(t *testing.T) { if err := sv.Filter.Validate(); err != nil { t.Errorf("%s filter spec invalid: %v", sv.Slug, err) } if err := sv.Render.Validate(); err != nil { t.Errorf("%s render spec invalid: %v", sv.Slug, err) } }) } } func TestSystemViews_SlugsReserved(t *testing.T) { for _, sv := range AllSystemViews() { t.Run(sv.Slug, func(t *testing.T) { if !IsReservedUserViewSlug(sv.Slug) { t.Errorf("system slug %q must be reserved against user_views", sv.Slug) } }) } } func TestReservedSlugs_CaseFolded(t *testing.T) { if !IsReservedUserViewSlug("Dashboard") { t.Error("reserved-slug check must be case-insensitive") } if !IsReservedUserViewSlug("INBOX") { t.Error("reserved-slug check must be case-insensitive") } } func TestReservedSlugs_NonReservedAccepted(t *testing.T) { cases := []string{"freitag-stand", "approval-pending-mine", "siemens", "my-view"} for _, slug := range cases { if IsReservedUserViewSlug(slug) { t.Errorf("user-friendly slug %q must not be reserved", slug) } } } // ---------------------------------------------------------------------- // InboxSystemView shape — t-paliad-249 // ---------------------------------------------------------------------- func TestInboxSystemView_Sources(t *testing.T) { sv := InboxSystemView() if !slices.Contains(sv.Filter.Sources, SourceApprovalRequest) { t.Errorf("InboxSystemView must include SourceApprovalRequest, got %v", sv.Filter.Sources) } if !slices.Contains(sv.Filter.Sources, SourceProjectEvent) { t.Errorf("InboxSystemView must include SourceProjectEvent, got %v", sv.Filter.Sources) } } func TestInboxSystemView_DefaultsToPast30d(t *testing.T) { sv := InboxSystemView() if sv.Filter.Time.Horizon != HorizonPast30d { t.Errorf("default horizon must be past_30d, got %q", sv.Filter.Time.Horizon) } } func TestInboxSystemView_RowActionInbox(t *testing.T) { sv := InboxSystemView() if sv.Render.List == nil { t.Fatal("InboxSystemView must define a list config") } if sv.Render.List.RowAction != RowActionInbox { t.Errorf("row_action must be inbox, got %q", sv.Render.List.RowAction) } } func TestInboxSystemView_CuratedProjectEventKinds(t *testing.T) { sv := InboxSystemView() preds := sv.Filter.Predicates[SourceProjectEvent] if preds.ProjectEvent == nil { t.Fatal("InboxSystemView must narrow project_event predicates") } got := preds.ProjectEvent.EventTypes if len(got) != len(InboxProjectEventKinds) { t.Errorf("expected %d curated kinds, got %d", len(InboxProjectEventKinds), len(got)) } for _, k := range got { if slices.Contains([]string{"status_changed", "project_created"}, k) { t.Errorf("inbox must NOT include noisy kind %q", k) } // No *_approval_* audit duplicates either — view_service dedups // at query time but the curated list shouldn't carry them. if isApprovalAuditKind(k) { t.Errorf("inbox curated list must not include audit-dup %q", k) } } } func TestInboxSystemView_NewestFirst(t *testing.T) { sv := InboxSystemView() if sv.Render.List == nil || sv.Render.List.Sort != SortDateDesc { t.Errorf("inbox must sort newest-first by default, got %q", sv.Render.List.Sort) } }