package server import ( "testing" "time" "chat-agent-system/internal/notification" ) func TestInboxSeverityRank(t *testing.T) { if inboxSeverityRank("proposal_required") != 0 { t.Fatalf("proposal_required should rank first") } if inboxSeverityRank("stage_ready_to_advance") != 1 { t.Fatalf("stage ready should be info rank") } } func TestUserNotificationViewFromCopiesCoreFields(t *testing.T) { n := notification.Notification{ ID: 9, UserID: 2, ProjectID: 3, Type: "stage_ready_to_advance", Title: "t", Body: "b", Status: "unread", CreatedAt: time.Unix(1, 0).UTC(), } v := userNotificationViewFrom(n) if v.ID != 9 || v.ProjectID != 3 || v.Title != "t" { t.Fatalf("unexpected view: %+v", v) } } func TestFanOutSortPrefersActionTypes(t *testing.T) { raw := []notification.Notification{ {ID: 1, Type: "stage_ready_to_advance"}, {ID: 2, Type: "proposal_required"}, {ID: 3, Type: "stage_ready_to_advance"}, } // mimic fanOut sort si := func(i, j int) bool { a, b := inboxSeverityRank(raw[i].Type), inboxSeverityRank(raw[j].Type) if a != b { return a < b } return raw[i].ID > raw[j].ID } // bubble for i := 0; i < len(raw); i++ { for j := i + 1; j < len(raw); j++ { if si(j, i) { raw[i], raw[j] = raw[j], raw[i] } } } if raw[0].Type != "proposal_required" { t.Fatalf("expected proposal first, got %+v", raw) } }