6a5d5a6119
27 tests covering POST /api/auth/login (9), POST /api/auth/register (9), and POST /api/webhooks/stripe (11). Routes are tested by importing handlers directly as functions, no HTTP server needed. Stripe false-positive fixed: thrown error message now differs from the hardcoded 400 response to verify sanitization.
108 lines
3.5 KiB
TypeScript
108 lines
3.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import '../../../__mocks__/prisma'
|
|
|
|
import { NextRequest } from 'next/server'
|
|
import { POST } from '@/app/api/auth/register/route'
|
|
import { prisma } from '@/lib/prisma'
|
|
import { mockUser } from '../../../fixtures/users'
|
|
|
|
vi.mock('@/lib/auth', async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import('@/lib/auth')>()
|
|
return {
|
|
...actual,
|
|
hashPassword: vi.fn().mockResolvedValue('$2a$12$hashedpassword'),
|
|
createSession: vi.fn().mockResolvedValue('mock-token'),
|
|
setSessionCookie: vi.fn(),
|
|
}
|
|
})
|
|
|
|
import { hashPassword, createSession, setSessionCookie } from '@/lib/auth'
|
|
|
|
function makeRequest(body: unknown) {
|
|
return new NextRequest(
|
|
new Request('http://localhost/api/auth/register', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
})
|
|
)
|
|
}
|
|
|
|
const validBody = {
|
|
email: 'newuser@example.com',
|
|
password: 'ValidPass123!',
|
|
name: 'Nuovo Utente',
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
vi.mocked(prisma.user.findUnique).mockResolvedValue(null)
|
|
vi.mocked(prisma.user.create).mockResolvedValue({ ...mockUser, email: validBody.email, name: validBody.name } as any)
|
|
vi.mocked(prisma.session.create).mockResolvedValue({} as any)
|
|
})
|
|
|
|
describe('POST /api/auth/register', () => {
|
|
it('returns 201 with user data on successful registration', async () => {
|
|
const res = await POST(makeRequest(validBody))
|
|
expect(res.status).toBe(201)
|
|
const data = await res.json()
|
|
expect(data.user.email).toBe(validBody.email)
|
|
expect(data.user).not.toHaveProperty('passwordHash')
|
|
})
|
|
|
|
it('hashes the password before storing', async () => {
|
|
await POST(makeRequest(validBody))
|
|
expect(hashPassword).toHaveBeenCalledWith(validBody.password)
|
|
const createCall = vi.mocked(prisma.user.create).mock.calls[0][0]
|
|
expect(createCall.data.passwordHash).toBe('$2a$12$hashedpassword')
|
|
})
|
|
|
|
it('creates a session and sets cookie after registration', async () => {
|
|
await POST(makeRequest(validBody))
|
|
expect(createSession).toHaveBeenCalled()
|
|
expect(setSessionCookie).toHaveBeenCalledWith('mock-token')
|
|
})
|
|
|
|
it('sets role to CUSTOMER', async () => {
|
|
await POST(makeRequest(validBody))
|
|
const createCall = vi.mocked(prisma.user.create).mock.calls[0][0]
|
|
expect(createCall.data.role).toBe('CUSTOMER')
|
|
})
|
|
|
|
it('returns 409 when email is already in use', async () => {
|
|
vi.mocked(prisma.user.findUnique).mockResolvedValue(mockUser as any)
|
|
|
|
const res = await POST(makeRequest(validBody))
|
|
expect(res.status).toBe(409)
|
|
const data = await res.json()
|
|
expect(data.error).toMatch(/already/)
|
|
})
|
|
|
|
it('returns 400 for invalid email', async () => {
|
|
const res = await POST(makeRequest({ ...validBody, email: 'not-an-email' }))
|
|
expect(res.status).toBe(400)
|
|
})
|
|
|
|
it('returns 400 for weak password (too short)', async () => {
|
|
const res = await POST(makeRequest({ ...validBody, password: 'Short1!' }))
|
|
expect(res.status).toBe(400)
|
|
})
|
|
|
|
it('returns 400 for empty name', async () => {
|
|
const res = await POST(makeRequest({ ...validBody, name: '' }))
|
|
expect(res.status).toBe(400)
|
|
})
|
|
|
|
it('returns 400 for malformed JSON', async () => {
|
|
const req = new NextRequest(
|
|
new Request('http://localhost/api/auth/register', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: 'bad-json',
|
|
})
|
|
)
|
|
const res = await POST(req)
|
|
expect(res.status).toBe(400)
|
|
})
|
|
})
|