/** * Bulk-dismiss service: dismissAllForPort must respect the optional rule/ * severity filter and never touch another port's alerts. */ import { describe, it, expect, beforeAll, vi } from 'vitest'; import { and, eq, isNull } from 'drizzle-orm'; vi.mock('@/lib/socket/server', () => ({ emitToRoom: vi.fn(), })); import { db } from '@/lib/db'; import { alerts } from '@/lib/db/schema/insights'; import { user } from '@/lib/db/schema/users'; import { dismissAllForPort } from '@/lib/services/alerts.service'; import { makePort } from '../helpers/factories'; let USER_ID = ''; beforeAll(async () => { const [u] = await db.select({ id: user.id }).from(user).limit(1); if (!u) throw new Error('No user available; run pnpm db:seed first'); USER_ID = u.id; }); async function seedAlert(portId: string, ruleId: string, severity = 'info') { const [row] = await db .insert(alerts) .values({ portId, ruleId, severity, title: `t-${ruleId}`, link: '/x', fingerprint: `fp-${Math.random().toString(36).slice(2)}`, metadata: {}, }) .returning({ id: alerts.id }); return row!.id; } async function openCount(portId: string) { const rows = await db .select() .from(alerts) .where(and(eq(alerts.portId, portId), isNull(alerts.dismissedAt), isNull(alerts.resolvedAt))); return rows.length; } describe('dismissAllForPort', () => { it('dismisses only the filtered rule, scoped to the port, then all', async () => { const portA = await makePort(); const portB = await makePort(); await seedAlert(portA.id, 'interest.stale'); await seedAlert(portA.id, 'interest.stale'); await seedAlert(portA.id, 'document.signer_overdue', 'warning'); await seedAlert(portB.id, 'interest.stale'); const filtered = await dismissAllForPort(portA.id, USER_ID, { ruleId: 'interest.stale' }); expect(filtered).toBe(2); expect(await openCount(portA.id)).toBe(1); // signer_overdue remains expect(await openCount(portB.id)).toBe(1); // other port untouched const rest = await dismissAllForPort(portA.id, USER_ID); expect(rest).toBe(1); expect(await openCount(portA.id)).toBe(0); expect(await openCount(portB.id)).toBe(1); }); });