import { beforeEach, describe, expect, it, vi } from 'vitest' import { buildMockRequest } from '../../../helpers/request' const authMock = vi.hoisted(() => ({ requireUserAuth: vi.fn(async () => ({ session: { user: { id: 'user-1' } }, })), isErrorResponse: vi.fn((value: unknown) => value instanceof Response), })) const prismaMock = vi.hoisted(() => ({ user: { findUnique: vi.fn<(...args: unknown[]) => Promise<{ id: string } | null>>(), }, userPreference: { upsert: vi.fn(async () => ({ userId: 'user-1', artStyle: 'realistic', })), }, })) vi.mock('@/lib/api-auth', () => authMock) vi.mock('@/lib/prisma', () => ({ prisma: prismaMock })) describe('api specific - user preference art style validation', () => { const routeContext = { params: Promise.resolve({}) } beforeEach(() => { vi.clearAllMocks() prismaMock.user.findUnique.mockResolvedValue({ id: 'user-1' }) }) it('accepts valid artStyle and persists normalized value', async () => { const mod = await import('@/app/api/user-preference/route') const req = buildMockRequest({ path: '/api/user-preference', method: 'PATCH', body: { artStyle: ' realistic ' }, }) const res = await mod.PATCH(req, routeContext) expect(res.status).toBe(200) expect(prismaMock.userPreference.upsert).toHaveBeenCalledWith( expect.objectContaining({ update: expect.objectContaining({ artStyle: 'realistic' }), }), ) }) it('rejects invalid artStyle with invalid params', async () => { const mod = await import('@/app/api/user-preference/route') const req = buildMockRequest({ path: '/api/user-preference', method: 'PATCH', body: { artStyle: 'anime' }, }) const res = await mod.PATCH(req, routeContext) const body = await res.json() expect(res.status).toBe(400) expect(body.error.code).toBe('INVALID_PARAMS') expect(prismaMock.userPreference.upsert).not.toHaveBeenCalled() }) it('returns unauthorized when session user record is missing', async () => { prismaMock.user.findUnique.mockResolvedValueOnce(null) const mod = await import('@/app/api/user-preference/route') const req = buildMockRequest({ path: '/api/user-preference', method: 'PATCH', body: { artStyle: 'realistic' }, }) const res = await mod.PATCH(req, routeContext) const body = await res.json() as { error?: { code?: string message?: string } } expect(res.status).toBe(401) expect(body.error?.code).toBe('UNAUTHORIZED') expect(body.error?.message).toBe('登录状态已失效,请重新登录') expect(prismaMock.userPreference.upsert).not.toHaveBeenCalled() }) })