import { beforeEach, describe, expect, it, vi } from 'vitest'; vi.mock('../../lib/sql.js', () => ({ sql: vi.fn(), })); vi.mock('../../lib/permission-middleware.js', () => ({ getUserFromRequest: vi.fn(), })); import { sql } from '../../lib/sql.js'; import { getUserFromRequest } from '../../lib/permission-middleware.js'; import handler from '../../pages/api/user/settings.js'; function createRes() { const res = { statusCode: 200, body: null, status(code) { res.statusCode = code; return res; }, json(data) { res.body = data; return res; }, }; return res; } const baseUserRow = { id: 1, email: 'a@b.c', role: 'user', first_name: 'A', last_name: 'B', username: 'ab', collection_visibility: 'private', preferred_currency: 'USD', cards_per_page: 50, default_view: 'grid', notifications_email: true, notifications_marketing: false, two_factor_enabled: false, theme: 'system', language: 'en', home_zip: '10001', created_at: '2026-01-01', updated_at: '2026-01-01', }; describe('/api/user/settings home_zip', () => { beforeEach(() => { vi.clearAllMocks(); getUserFromRequest.mockResolvedValue({ userId: 1, email: 'a@b.c', role: 'user' }); }); it('GET includes home_zip in settings', async () => { sql.mockResolvedValue({ rows: [baseUserRow] }); const res = createRes(); await handler({ method: 'GET' }, res); expect(res.statusCode).toBe(200); expect(res.body.settings.home_zip).toBe('10001'); }); it('PUT persists valid 5-digit zip', async () => { sql.query = vi.fn().mockResolvedValue({ rows: [{ ...baseUserRow, home_zip: '90210' }], }); const res = createRes(); await handler({ method: 'PUT', body: { home_zip: '90210' } }, res); expect(res.statusCode).toBe(200); expect(res.body.settings.home_zip).toBe('90210'); expect(sql.query).toHaveBeenCalled(); const queryText = sql.query.mock.calls[0][0]; expect(queryText).toContain('home_zip'); }); it('PUT rejects invalid zip', async () => { const res = createRes(); await handler({ method: 'PUT', body: { home_zip: '1234' } }, res); expect(res.statusCode).toBe(400); expect(res.body.error).toMatch(/zip/i); }); it('PUT allows null to clear zip', async () => { sql.query = vi.fn().mockResolvedValue({ rows: [{ ...baseUserRow, home_zip: null }], }); const res = createRes(); await handler({ method: 'PUT', body: { home_zip: null } }, res); expect(res.statusCode).toBe(200); expect(res.body.settings.home_zip).toBeNull(); }); });