test: add Vitest infrastructure (config, setup, mocks, fixtures)
Adds test harness for the suite: - vitest.config.ts: happy-dom env, @/* alias, v8 coverage with 70% thresholds - setup.ts: env vars, global next/headers and next/navigation mocks - tsconfig.json: IDE alias resolution for test/ - __mocks__/prisma.ts: centralised Prisma mock auto-registered via vi.mock - fixtures/users.ts, fixtures/orders.ts: typed test data
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import { vi } from 'vitest'
|
||||
|
||||
export const prisma = {
|
||||
user: {
|
||||
findUnique: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
create: vi.fn(),
|
||||
update: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
count: vi.fn(),
|
||||
},
|
||||
session: {
|
||||
create: vi.fn(),
|
||||
findUnique: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
deleteMany: vi.fn(),
|
||||
},
|
||||
loginAttempt: {
|
||||
count: vi.fn(),
|
||||
create: vi.fn(),
|
||||
deleteMany: vi.fn(),
|
||||
},
|
||||
order: {
|
||||
create: vi.fn(),
|
||||
update: vi.fn(),
|
||||
findUnique: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
count: vi.fn(),
|
||||
},
|
||||
orderItem: {
|
||||
create: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
},
|
||||
payment: {
|
||||
create: vi.fn(),
|
||||
update: vi.fn(),
|
||||
updateMany: vi.fn(),
|
||||
findFirst: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
},
|
||||
product: {
|
||||
findUnique: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
create: vi.fn(),
|
||||
update: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
count: vi.fn(),
|
||||
},
|
||||
productType: {
|
||||
findUnique: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
create: vi.fn(),
|
||||
update: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
},
|
||||
category: {
|
||||
findUnique: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
create: vi.fn(),
|
||||
update: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
},
|
||||
review: {
|
||||
findMany: vi.fn(),
|
||||
create: vi.fn(),
|
||||
update: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
count: vi.fn(),
|
||||
},
|
||||
auditLog: {
|
||||
create: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
},
|
||||
siteSettings: {
|
||||
findMany: vi.fn(),
|
||||
upsert: vi.fn(),
|
||||
},
|
||||
$transaction: vi.fn((fn: (tx: unknown) => unknown) => fn(prisma)),
|
||||
}
|
||||
|
||||
vi.mock('@/lib/prisma', () => ({ prisma }))
|
||||
Vendored
+53
@@ -0,0 +1,53 @@
|
||||
import { mockUser } from './users'
|
||||
|
||||
export const mockOrder = {
|
||||
id: 'order-1',
|
||||
userId: mockUser.id,
|
||||
status: 'PENDING' as const,
|
||||
grandTotal: 2999,
|
||||
currency: 'EUR',
|
||||
createdAt: new Date('2024-01-01'),
|
||||
updatedAt: new Date('2024-01-01'),
|
||||
user: mockUser,
|
||||
}
|
||||
|
||||
export const mockPayment = {
|
||||
id: 'payment-1',
|
||||
orderId: mockOrder.id,
|
||||
provider: 'stripe',
|
||||
providerPaymentId: 'pi_test_123',
|
||||
status: 'pending',
|
||||
amount: 2999,
|
||||
currency: 'EUR',
|
||||
rawPayload: {},
|
||||
createdAt: new Date('2024-01-01'),
|
||||
updatedAt: new Date('2024-01-01'),
|
||||
}
|
||||
|
||||
export const mockStripeCheckoutEvent = {
|
||||
type: 'checkout.session.completed',
|
||||
data: {
|
||||
object: {
|
||||
metadata: { orderId: mockOrder.id },
|
||||
payment_intent: 'pi_test_123',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const mockStripePaymentSucceededEvent = {
|
||||
type: 'payment_intent.succeeded',
|
||||
data: {
|
||||
object: {
|
||||
id: 'pi_test_123',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const mockStripePaymentFailedEvent = {
|
||||
type: 'payment_intent.payment_failed',
|
||||
data: {
|
||||
object: {
|
||||
id: 'pi_test_123',
|
||||
},
|
||||
},
|
||||
}
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
export const mockUser = {
|
||||
id: 'user-1',
|
||||
email: 'test@example.com',
|
||||
name: 'Test User',
|
||||
passwordHash: '$2a$12$hashedpassword',
|
||||
role: 'CUSTOMER' as const,
|
||||
mustChangePassword: false,
|
||||
createdAt: new Date('2024-01-01'),
|
||||
updatedAt: new Date('2024-01-01'),
|
||||
}
|
||||
|
||||
export const mockAdmin = {
|
||||
...mockUser,
|
||||
id: 'admin-1',
|
||||
email: 'admin@example.com',
|
||||
name: 'Admin User',
|
||||
role: 'ADMIN' as const,
|
||||
}
|
||||
|
||||
export const mockSession = {
|
||||
id: 'session-1',
|
||||
userId: mockUser.id,
|
||||
tokenHash: 'abc123hash',
|
||||
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
|
||||
createdAt: new Date('2024-01-01'),
|
||||
user: mockUser,
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import '@testing-library/jest-dom'
|
||||
import { vi } from 'vitest'
|
||||
|
||||
// Env vars necessarie per i test
|
||||
process.env.STRIPE_SECRET_KEY = 'sk_test_mock'
|
||||
process.env.STRIPE_WEBHOOK_SECRET = 'whsec_test_mock'
|
||||
process.env.SMTP_HOST = 'localhost'
|
||||
process.env.SMTP_PORT = '1025'
|
||||
process.env.APP_URL = 'http://localhost'
|
||||
process.env.DATABASE_URL = 'postgresql://test:test@localhost:5432/test'
|
||||
process.env.NODE_ENV = 'test'
|
||||
process.env.AUTH_SECRET = 'test-secret-32-chars-minimum-ok!'
|
||||
|
||||
// Mock di next/headers (cookies() lancia fuori dal runtime Next.js)
|
||||
vi.mock('next/headers', () => {
|
||||
const mockCookieStore = {
|
||||
get: vi.fn(),
|
||||
set: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
}
|
||||
return {
|
||||
cookies: vi.fn(() => mockCookieStore),
|
||||
}
|
||||
})
|
||||
|
||||
// Mock di next/navigation
|
||||
vi.mock('next/navigation', () => ({
|
||||
useRouter: vi.fn(() => ({ push: vi.fn(), replace: vi.fn() })),
|
||||
usePathname: vi.fn(() => '/'),
|
||||
redirect: vi.fn(),
|
||||
}))
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "../app/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["../app/src/*"]
|
||||
},
|
||||
"types": ["vitest/globals", "@testing-library/jest-dom"]
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts",
|
||||
"./**/*.tsx"
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import path from 'path'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: 'happy-dom',
|
||||
globals: true,
|
||||
setupFiles: [path.resolve(__dirname, 'setup.ts')],
|
||||
include: [
|
||||
'../test/unit/**/*.{test,spec}.{ts,tsx}',
|
||||
'../test/integration/**/*.{test,spec}.{ts,tsx}',
|
||||
'../test/components/**/*.{test,spec}.{ts,tsx}',
|
||||
],
|
||||
exclude: ['**/node_modules/**'],
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: ['text', 'html', 'lcov'],
|
||||
include: ['src/**/*.ts', 'src/**/*.tsx'],
|
||||
exclude: [
|
||||
'src/app/layout.tsx',
|
||||
'src/lib/prisma.ts',
|
||||
'src/**/*.d.ts',
|
||||
],
|
||||
thresholds: { lines: 70, functions: 70 },
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '../app/src'),
|
||||
},
|
||||
},
|
||||
esbuild: {
|
||||
jsx: 'automatic',
|
||||
jsxImportSource: 'react',
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user