package engine import ( "testing" "time" "github.com/local/glpi-neural-brain/internal/config" "github.com/local/glpi-neural-brain/internal/sourceagent" ) func testInboxEngine() *Engine { return &Engine{Cfg: config.Config{SourceInboxMinSimilarity: .55, SourceInboxMinPriority: .55, SourceInboxNoveltyFloor: .35}} } func TestSourceInboxSecurityAlertCanBecomeCandidateBelowSemanticThreshold(t *testing.T) { now := time.Date(2026, 8, 7, 20, 0, 0, 0, time.UTC) item := sourceagent.InboxDocument{Document: sourceagent.Document{Title: "Veeam One für Schadcode-Attacken anfällig", PublishedAt: now.Add(-2 * time.Hour), SourceName: "heise Security - Nur die Alerts", Categories: []string{"Security", "Alerts"}}, ReceivedAt: now} got := testInboxEngine().classifySourceInboxItem(item, .49, "kb-veeam", now) if got.Status != "candidate" || got.Priority < .55 || got.Semantic != .49 { t.Fatalf("curated fresh security alert should remain searchable, got %+v", got) } } func TestSourceInboxNoveltyFloorStillArchivesUnrelatedAlert(t *testing.T) { now := time.Date(2026, 8, 7, 20, 0, 0, 0, time.UTC) item := sourceagent.InboxDocument{Document: sourceagent.Document{Title: "Critical Security Advisory for unrelated appliance", PublishedAt: now, SourceName: "Security Alerts", Categories: []string{"Security"}}, ReceivedAt: now} got := testInboxEngine().classifySourceInboxItem(item, .21, "kb-unrelated", now) if got.Status != "archived" { t.Fatalf("very low KB proximity must still be archived, got %+v", got) } } func TestSourceInboxHighSemanticSimilarityRemainsCandidate(t *testing.T) { now := time.Now().UTC() item := sourceagent.InboxDocument{Document: sourceagent.Document{Title: "Evergreen Backup Guide"}, ReceivedAt: now.Add(-200 * 24 * time.Hour)} got := testInboxEngine().classifySourceInboxItem(item, .72, "kb-backup", now) if got.Status != "candidate" { t.Fatalf("direct semantic match must remain candidate, got %+v", got) } }