import { describe, it, expect } from 'vitest' import { loginSchema, registerSchema, changePasswordSchema, productTypeSchema, productSchema, categorySchema, reviewSchema, cartItemSchema, checkoutSchema, settingSchema, } from '@/lib/validate' // ─── loginSchema ──────────────────────────────────────────────────────────── describe('loginSchema', () => { it('accepts valid email and password', () => { const result = loginSchema.safeParse({ email: 'user@example.com', password: 'anypass' }) expect(result.success).toBe(true) }) it('rejects invalid email', () => { const result = loginSchema.safeParse({ email: 'not-an-email', password: 'pass' }) expect(result.success).toBe(false) expect(result.error?.errors[0].message).toBe('Invalid email address') }) it('rejects empty password', () => { const result = loginSchema.safeParse({ email: 'user@example.com', password: '' }) expect(result.success).toBe(false) }) it('rejects missing fields', () => { expect(loginSchema.safeParse({}).success).toBe(false) }) }) // ─── registerSchema ────────────────────────────────────────────────────────── describe('registerSchema', () => { const valid = { email: 'user@example.com', password: 'ValidPass123!', name: 'Mario Rossi', } it('accepts valid registration data', () => { expect(registerSchema.safeParse(valid).success).toBe(true) }) it('rejects password shorter than 12 chars', () => { const r = registerSchema.safeParse({ ...valid, password: 'Short1!' }) expect(r.success).toBe(false) expect(r.error?.errors[0].message).toMatch(/12 characters/) }) it('rejects password without uppercase', () => { const r = registerSchema.safeParse({ ...valid, password: 'nouppercase1!' }) expect(r.success).toBe(false) expect(r.error?.errors[0].message).toMatch(/uppercase/) }) it('rejects password without lowercase', () => { const r = registerSchema.safeParse({ ...valid, password: 'NOLOWERCASE1!' }) expect(r.success).toBe(false) expect(r.error?.errors[0].message).toMatch(/lowercase/) }) it('rejects password without number', () => { const r = registerSchema.safeParse({ ...valid, password: 'NoNumberHere!' }) expect(r.success).toBe(false) expect(r.error?.errors[0].message).toMatch(/number/) }) it('rejects password without symbol', () => { const r = registerSchema.safeParse({ ...valid, password: 'NoSymbolHere1' }) expect(r.success).toBe(false) expect(r.error?.errors[0].message).toMatch(/symbol/) }) it('rejects empty name', () => { const r = registerSchema.safeParse({ ...valid, name: '' }) expect(r.success).toBe(false) }) it('rejects name longer than 100 chars', () => { const r = registerSchema.safeParse({ ...valid, name: 'a'.repeat(101) }) expect(r.success).toBe(false) }) }) // ─── changePasswordSchema ──────────────────────────────────────────────────── describe('changePasswordSchema', () => { it('accepts valid passwords', () => { const r = changePasswordSchema.safeParse({ currentPassword: 'OldPass1!', newPassword: 'NewStrongPass1!', }) expect(r.success).toBe(true) }) it('rejects empty currentPassword', () => { const r = changePasswordSchema.safeParse({ currentPassword: '', newPassword: 'NewStrongPass1!', }) expect(r.success).toBe(false) }) it('rejects weak newPassword', () => { const r = changePasswordSchema.safeParse({ currentPassword: 'OldPass1!', newPassword: 'weak', }) expect(r.success).toBe(false) }) }) // ─── productTypeSchema ─────────────────────────────────────────────────────── describe('productTypeSchema', () => { const valid = { name: 'Abbigliamento', slug: 'abbigliamento', schema: { color: 'string' } } it('accepts valid product type', () => { expect(productTypeSchema.safeParse(valid).success).toBe(true) }) it('rejects slug with uppercase', () => { const r = productTypeSchema.safeParse({ ...valid, slug: 'Abbigliamento' }) expect(r.success).toBe(false) }) it('rejects slug with spaces', () => { const r = productTypeSchema.safeParse({ ...valid, slug: 'con spazio' }) expect(r.success).toBe(false) }) it('accepts slug with hyphens and numbers', () => { const r = productTypeSchema.safeParse({ ...valid, slug: 'tipo-123' }) expect(r.success).toBe(true) }) it('rejects empty name', () => { expect(productTypeSchema.safeParse({ ...valid, name: '' }).success).toBe(false) }) }) // ─── productSchema ─────────────────────────────────────────────────────────── describe('productSchema', () => { const valid = { typeId: 'type-1', title: 'Maglietta', slug: 'maglietta', description: 'Una bella maglietta', basePrice: 1999, currency: 'EUR', status: 'DRAFT' as const, attributes: {}, } it('accepts valid product', () => { expect(productSchema.safeParse(valid).success).toBe(true) }) it('rejects negative price', () => { const r = productSchema.safeParse({ ...valid, basePrice: -1 }) expect(r.success).toBe(false) }) it('accepts price = 0', () => { const r = productSchema.safeParse({ ...valid, basePrice: 0 }) expect(r.success).toBe(true) }) it('rejects currency not 3 chars', () => { const r = productSchema.safeParse({ ...valid, currency: 'EU' }) expect(r.success).toBe(false) }) it('rejects invalid status', () => { const r = productSchema.safeParse({ ...valid, status: 'INVALID' }) expect(r.success).toBe(false) }) it('accepts all valid statuses', () => { for (const status of ['DRAFT', 'PUBLISHED', 'ARCHIVED'] as const) { expect(productSchema.safeParse({ ...valid, status }).success).toBe(true) } }) it('accepts optional categoryIds', () => { const r = productSchema.safeParse({ ...valid, categoryIds: ['cat-1', 'cat-2'] }) expect(r.success).toBe(true) }) it('rejects non-integer price', () => { const r = productSchema.safeParse({ ...valid, basePrice: 19.99 }) expect(r.success).toBe(false) }) }) // ─── categorySchema ────────────────────────────────────────────────────────── describe('categorySchema', () => { const valid = { name: 'Uomo', slug: 'uomo' } it('accepts valid category', () => { expect(categorySchema.safeParse(valid).success).toBe(true) }) it('accepts category with parentId', () => { expect(categorySchema.safeParse({ ...valid, parentId: 'parent-1' }).success).toBe(true) }) it('accepts parentId = null', () => { expect(categorySchema.safeParse({ ...valid, parentId: null }).success).toBe(true) }) it('rejects slug with special chars', () => { const r = categorySchema.safeParse({ ...valid, slug: 'cat@home' }) expect(r.success).toBe(false) }) }) // ─── reviewSchema ──────────────────────────────────────────────────────────── describe('reviewSchema', () => { const valid = { productId: 'prod-1', rating: 4 } it('accepts valid review', () => { expect(reviewSchema.safeParse(valid).success).toBe(true) }) it('rejects rating 0', () => { expect(reviewSchema.safeParse({ ...valid, rating: 0 }).success).toBe(false) }) it('rejects rating 6', () => { expect(reviewSchema.safeParse({ ...valid, rating: 6 }).success).toBe(false) }) it('accepts all valid ratings 1-5', () => { for (const rating of [1, 2, 3, 4, 5]) { expect(reviewSchema.safeParse({ ...valid, rating }).success).toBe(true) } }) it('rejects comment longer than 2000 chars', () => { const r = reviewSchema.safeParse({ ...valid, comment: 'a'.repeat(2001) }) expect(r.success).toBe(false) }) it('accepts title up to 200 chars', () => { expect(reviewSchema.safeParse({ ...valid, title: 'a'.repeat(200) }).success).toBe(true) }) }) // ─── cartItemSchema ────────────────────────────────────────────────────────── describe('cartItemSchema', () => { const valid = { productId: 'prod-1', quantity: 2 } it('accepts valid cart item', () => { expect(cartItemSchema.safeParse(valid).success).toBe(true) }) it('rejects quantity 0', () => { expect(cartItemSchema.safeParse({ ...valid, quantity: 0 }).success).toBe(false) }) it('rejects quantity over 100', () => { expect(cartItemSchema.safeParse({ ...valid, quantity: 101 }).success).toBe(false) }) it('accepts quantity = 100', () => { expect(cartItemSchema.safeParse({ ...valid, quantity: 100 }).success).toBe(true) }) it('accepts optional variantId', () => { expect(cartItemSchema.safeParse({ ...valid, variantId: 'var-1' }).success).toBe(true) }) }) // ─── checkoutSchema ────────────────────────────────────────────────────────── describe('checkoutSchema', () => { const valid = { items: [{ productId: 'prod-1', quantity: 1 }] } it('accepts valid checkout', () => { expect(checkoutSchema.safeParse(valid).success).toBe(true) }) it('rejects empty items array', () => { const r = checkoutSchema.safeParse({ items: [] }) expect(r.success).toBe(false) expect(r.error?.errors[0].message).toBe('Cart is empty') }) it('accepts multiple items', () => { const r = checkoutSchema.safeParse({ items: [ { productId: 'prod-1', quantity: 2 }, { productId: 'prod-2', quantity: 1 }, ], }) expect(r.success).toBe(true) }) }) // ─── settingSchema ─────────────────────────────────────────────────────────── describe('settingSchema', () => { it('accepts valid setting', () => { expect(settingSchema.safeParse({ key: 'site_name', value: 'My Shop' }).success).toBe(true) }) it('rejects empty key', () => { expect(settingSchema.safeParse({ key: '', value: 'anything' }).success).toBe(false) }) it('accepts any value type', () => { for (const value of ['string', 42, true, null, { nested: true }]) { expect(settingSchema.safeParse({ key: 'k', value }).success).toBe(true) } }) })