Files
Agent-System/internal/server/notification_list_all_test.go
weichen 143ee934b8 feat(collab): free-lane chat, claim-on-view, lease ownership, notify inbox
Open member free-lane for chat initiation; auto-claim on author view;
harden lease persist/ownership with readable DOC_BUSY; add notification
inbox and supplement-impact HTTP decision APIs wired to composition root.
2026-09-24 11:49:43 +00:00

56 lines
1.3 KiB
Go

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)
}
}