package alerts import ( "context" "io" "log/slog" "os" "testing" "time" "data-terminal-cloud/internal/database" "github.com/google/uuid" ) func TestScannerDetectsExpiringCertificateInventory(t *testing.T) { databaseURL := os.Getenv("TEST_DATABASE_URL") if databaseURL == "" { t.Skip("TEST_DATABASE_URL is not set") } ctx := context.Background() pool, err := database.Open(ctx, databaseURL, "certificate-alert-test") if err != nil { t.Fatal(err) } defer pool.Close() tenantID := "10000000-0000-0000-0000-000000000001" var userID string if err = pool.QueryRow(ctx, `SELECT id::text FROM user_account WHERE tenant_id=$1::uuid ORDER BY created_at LIMIT 1`, tenantID).Scan(&userID); err != nil { t.Fatal(err) } publicID := uuid.NewString() name := "cert-manager://integration/" + publicID now := time.Now().UTC().Truncate(time.Second) if _, err = pool.Exec(ctx, `INSERT INTO ops_resource_reference(public_id,tenant_id,resource_type,reference_name,display_name,verified_at,expires_at,created_by) VALUES($1::uuid,$2::uuid,'CERTIFICATE',$3,'集成测试证书',$4,$5,$6::uuid)`, publicID, tenantID, name, now.Add(-time.Hour), now.Add(5*24*time.Hour), userID); err != nil { t.Fatal(err) } defer func() { _, _ = pool.Exec(context.Background(), `DELETE FROM alert_incident WHERE tenant_id=$1::uuid AND fingerprint=$2`, tenantID, "certificate-expiring:"+publicID) _, _ = pool.Exec(context.Background(), `DELETE FROM ops_resource_reference WHERE tenant_id=$1::uuid AND public_id=$2::uuid`, tenantID, publicID) }() scanner, err := NewScanner(pool, slog.New(slog.NewTextHandler(io.Discard, nil)), time.Second) if err != nil { t.Fatal(err) } scanner.now = func() time.Time { return now } if _, err = scanner.ScanOnce(ctx); err != nil { t.Fatal(err) } var rule, category, severity, resourceID string if err = pool.QueryRow(ctx, `SELECT rule_code,category,severity,resource_public_id::text FROM alert_incident WHERE tenant_id=$1::uuid AND fingerprint=$2`, tenantID, "certificate-expiring:"+publicID).Scan(&rule, &category, &severity, &resourceID); err != nil { t.Fatal(err) } if rule != "CERTIFICATE_EXPIRING" || category != "SECURITY" || severity != "CRITICAL" || resourceID != publicID { t.Fatalf("rule=%s category=%s severity=%s resource=%s", rule, category, severity, resourceID) } }