import { describe, it, expect, vi, beforeEach } from 'vitest' vi.mock('next/headers', () => ({ cookies: vi.fn().mockResolvedValue({}) })) vi.mock('iron-session', () => ({ getIronSession: vi.fn().mockResolvedValue({ userId: 'user-1', isDemo: false }), })) vi.mock('@/lib/session', () => ({ sessionOptions: { cookieName: 'test', password: 'test' }, })) vi.mock('@/lib/prisma', () => ({ prisma: { user: { findUnique: vi.fn() }, $transaction: vi.fn(async (fn: (tx: unknown) => Promise) => { return fn({ user: { findUnique: vi.fn().mockResolvedValue({ settings: {} }), update: vi.fn().mockResolvedValue({}), }, }) }), $executeRaw: vi.fn().mockResolvedValue(1), }, })) import { prisma } from '@/lib/prisma' import { getIronSession } from 'iron-session' import { updateUserSettingsAction } from '@/actions/user-settings' const mockPrisma = prisma as unknown as { user: { findUnique: ReturnType } $transaction: ReturnType $executeRaw: ReturnType } const mockGetIronSession = getIronSession as ReturnType beforeEach(() => { vi.clearAllMocks() mockGetIronSession.mockResolvedValue({ userId: 'user-1', isDemo: false }) mockPrisma.$executeRaw.mockResolvedValue(1) }) describe('updateUserSettingsAction', () => { it('returns 401 when not logged in', async () => { mockGetIronSession.mockResolvedValue({ userId: undefined, isDemo: false }) const result = await updateUserSettingsAction({}) expect(result).toEqual({ error: 'Niet ingelogd', code: 401 }) }) it('returns 403 for demo accounts', async () => { mockGetIronSession.mockResolvedValue({ userId: 'user-1', isDemo: true }) const result = await updateUserSettingsAction({}) expect('error' in result && result.code).toBe(403) }) it('returns 422 when patch is invalid', async () => { const result = await updateUserSettingsAction({ views: { sprintBacklog: { filterStatus: 'NONSENSE' } }, } as never) expect('error' in result && result.code).toBe(422) }) it('merges with current settings and emits notify on success', async () => { const existingFindUnique = vi.fn().mockResolvedValue({ settings: { views: { sprintBacklog: { sort: 'code' } } }, }) const update = vi.fn().mockResolvedValue({}) mockPrisma.$transaction.mockImplementationOnce(async (fn: (tx: unknown) => Promise) => { return fn({ user: { findUnique: existingFindUnique, update } }) }) const result = await updateUserSettingsAction({ views: { sprintBacklog: { sortDir: 'desc' } }, }) expect('success' in result && result.success).toBe(true) expect(update).toHaveBeenCalledWith({ where: { id: 'user-1' }, data: { settings: { views: { sprintBacklog: { sort: 'code', sortDir: 'desc' } } } }, }) expect(mockPrisma.$executeRaw).toHaveBeenCalled() }) })