- All 8 home page sections: Hero, Locations slider, WhyParents accordion, Birthday pricing cards, Video, Gallery, Reviews slider, News - UI components: NavLink, BtnPrimary, BtnGradient, BtnDetails, AccordionItem - Layout: sticky Header (NavLink + BtnPrimary), Footer with logo - Figma Code Connect: 5 components published (.figma.tsx + figma.config.json) - Public assets: all Figma images and SVGs exported - Pages: /kvytky, /lokatsii, /blog, /dni-narodzhennia, /grupovi-vidviduvannia - Tests: Vitest unit/api suites, Playwright e2e screenshots - Payload CMS: blocks, collections, seed data updates - Hero negative-margin to extend behind sticky header - Custom Tailwind breakpoints: lg=1440px, xl=1920px - Fix ESLint config: drop FlatCompat, use eslint-config-next flat export - Add tsconfig.tsbuildinfo, test-results/, agentdb.rvf* to .gitignore Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
|
|
const mockSend = vi.fn()
|
|
vi.mock('resend', () => ({
|
|
Resend: vi.fn(function MockResend() {
|
|
return { emails: { send: mockSend } }
|
|
}),
|
|
}))
|
|
vi.mock('@react-email/components', () => ({ render: vi.fn(async () => '<html>email</html>') }))
|
|
vi.mock('@/emails/LeadAlert', () => ({ LeadAlertEmail: vi.fn(() => null) }))
|
|
|
|
const LEAD = {
|
|
name: 'Іван Іванов',
|
|
phone: '+380501234567',
|
|
formSource: 'hero-form',
|
|
}
|
|
|
|
let sendLeadAlert: (lead: typeof LEAD & { email?: string; utmSource?: string }) => Promise<void>
|
|
|
|
beforeEach(async () => {
|
|
vi.resetModules()
|
|
mockSend.mockReset()
|
|
vi.stubEnv('RESEND_API_KEY', 're_test_key')
|
|
vi.stubEnv('MANAGER_EMAILS', 'manager@shumiland.ua')
|
|
const mod = await import('@/lib/resend')
|
|
sendLeadAlert = mod.sendLeadAlert
|
|
})
|
|
|
|
describe('sendLeadAlert', () => {
|
|
it('sends email to all configured manager addresses', async () => {
|
|
mockSend.mockResolvedValueOnce({})
|
|
await sendLeadAlert(LEAD)
|
|
expect(mockSend).toHaveBeenCalledOnce()
|
|
const call = mockSend.mock.calls[0]![0]!
|
|
expect(call.to).toContain('manager@shumiland.ua')
|
|
})
|
|
|
|
it('includes the lead name and formSource in the email subject', async () => {
|
|
mockSend.mockResolvedValueOnce({})
|
|
await sendLeadAlert(LEAD)
|
|
const { subject } = mockSend.mock.calls[0]![0]!
|
|
expect(subject).toContain('Іван Іванов')
|
|
expect(subject).toContain('hero-form')
|
|
})
|
|
|
|
it('skips sending when MANAGER_EMAILS is not configured', async () => {
|
|
vi.stubEnv('MANAGER_EMAILS', '')
|
|
vi.resetModules()
|
|
const mod = await import('@/lib/resend')
|
|
await mod.sendLeadAlert(LEAD)
|
|
expect(mockSend).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('does not throw when resend.emails.send rejects', async () => {
|
|
mockSend.mockRejectedValueOnce(new Error('API error'))
|
|
await expect(sendLeadAlert(LEAD)).resolves.not.toThrow()
|
|
})
|
|
|
|
it('sends to all managers when MANAGER_EMAILS is comma-separated', async () => {
|
|
vi.stubEnv('MANAGER_EMAILS', 'a@example.com,b@example.com')
|
|
vi.resetModules()
|
|
const mod = await import('@/lib/resend')
|
|
mockSend.mockResolvedValueOnce({})
|
|
await mod.sendLeadAlert(LEAD)
|
|
const { to } = mockSend.mock.calls[0]![0]!
|
|
expect(to).toContain('a@example.com')
|
|
expect(to).toContain('b@example.com')
|
|
})
|
|
})
|