import { describe, expect, it, vi } from "vitest"; import { SystemRole } from "@nexus/shared"; vi.mock("@nexus/application", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, getDashboardBudgetForecast: vi.fn().mockResolvedValue([]), getDashboardPeakTimes: vi.fn().mockResolvedValue([]), listAssignmentBookings: vi.fn().mockResolvedValue([]), }; }); import { executeTool } from "../router/assistant-tools.js"; import { createToolContext, withUserLookup } from "./assistant-tools-notification-test-helpers.js"; describe("assistant reminder mutation tools - success", () => { it("parses reminder datetimes and forwards optional reminder fields", async () => { const db = withUserLookup({ notification: { create: vi.fn().mockResolvedValue({ id: "rem_1", title: "Check holiday setup", category: "REMINDER", }), }, }); const ctx = createToolContext(db, SystemRole.USER); const result = await executeTool( "create_reminder", JSON.stringify({ title: "Check holiday setup", body: "Compare Bavaria and Hamburg", remindAt: "2026-05-02T10:15:00.000Z", recurrence: "monthly", entityId: "calendar_1", entityType: "HOLIDAY_CALENDAR", link: "/holidays", }), ctx, ); expect(db.notification.create).toHaveBeenCalledWith({ data: { userId: "user_1", type: "REMINDER", category: "REMINDER", title: "Check holiday setup", body: "Compare Bavaria and Hamburg", remindAt: new Date("2026-05-02T10:15:00.000Z"), nextRemindAt: new Date("2026-05-02T10:15:00.000Z"), recurrence: "monthly", entityId: "calendar_1", entityType: "HOLIDAY_CALENDAR", link: "/holidays", channel: "in_app", }, }); expect(result.action).toEqual({ type: "invalidate", scope: ["notification"] }); expect(result.data).toEqual( expect.objectContaining({ success: true, reminderId: "rem_1", message: 'Reminder "Check holiday setup" created.', }), ); }); it("updates reminders through the real router path and invalidates notification queries", async () => { const remindAt = new Date("2026-05-01T07:00:00.000Z"); const db = withUserLookup({ notification: { findFirst: vi.fn().mockResolvedValue({ id: "rem_1", userId: "user_1", category: "REMINDER", }), update: vi.fn().mockResolvedValue({ id: "rem_1", title: "Updated reminder", remindAt, nextRemindAt: remindAt, recurrence: null, }), }, }); const ctx = createToolContext(db, SystemRole.USER); const result = await executeTool( "update_reminder", JSON.stringify({ id: "rem_1", title: "Updated reminder", remindAt: "2026-05-01T07:00:00.000Z", recurrence: null, }), ctx, ); expect(db.notification.findFirst).toHaveBeenCalledWith({ where: { id: "rem_1", userId: "user_1", category: "REMINDER" }, }); expect(db.notification.update).toHaveBeenCalledWith({ where: { id: "rem_1" }, data: { title: "Updated reminder", remindAt, nextRemindAt: remindAt, recurrence: null, }, }); expect(result.action).toEqual({ type: "invalidate", scope: ["notification"] }); expect(result.data).toEqual( expect.objectContaining({ success: true, reminderId: "rem_1", message: "Updated reminder rem_1.", reminder: expect.objectContaining({ id: "rem_1", title: "Updated reminder", recurrence: null, }), }), ); }); it("deletes reminders through the router and returns notification invalidation metadata", async () => { const db = withUserLookup({ notification: { findFirst: vi.fn().mockResolvedValue({ id: "rem_1", userId: "user_1", category: "REMINDER", }), delete: vi.fn().mockResolvedValue({ id: "rem_1" }), }, }); const ctx = createToolContext(db, SystemRole.USER); const result = await executeTool("delete_reminder", JSON.stringify({ id: "rem_1" }), ctx); expect(db.notification.delete).toHaveBeenCalledWith({ where: { id: "rem_1" } }); expect(result.action).toEqual({ type: "invalidate", scope: ["notification"] }); expect(result.data).toEqual({ success: true, id: "rem_1", message: "Deleted reminder rem_1.", }); }); });