diff --git a/supabase/functions/_shared/email.test.ts b/supabase/functions/_shared/email.test.ts new file mode 100644 index 0000000..9961f06 --- /dev/null +++ b/supabase/functions/_shared/email.test.ts @@ -0,0 +1,49 @@ +import { assertEquals, assertStringIncludes } from 'jsr:@std/assert' +import { buildBookingNotificationEmail, buildInquiryNotificationEmail } from './email.ts' + +Deno.test('buildBookingNotificationEmail includes the service, date, time, and contact details', () => { + const { subject, html } = buildBookingNotificationEmail({ + serviceName: 'Knotless Braids', + date: '2026-09-01', + time: '10:00 AM', + contact: { name: 'Jane Doe', phone: '555-0100', email: 'jane@example.com', notes: 'First time client' }, + }) + assertEquals(subject, 'New booking: Knotless Braids on 2026-09-01') + assertStringIncludes(html, 'Jane Doe') + assertStringIncludes(html, 'Knotless Braids') + assertStringIncludes(html, '2026-09-01') + assertStringIncludes(html, '10:00 AM') + assertStringIncludes(html, '555-0100') + assertStringIncludes(html, 'jane@example.com') + assertStringIncludes(html, 'First time client') +}) + +Deno.test('buildBookingNotificationEmail omits the notes paragraph when notes are empty', () => { + const { html } = buildBookingNotificationEmail({ + serviceName: 'Cornrows', + date: '2026-09-02', + time: '1:00 PM', + contact: { name: 'Amy', phone: '555-0101', email: 'amy@example.com', notes: '' }, + }) + if (html.includes('Notes:')) throw new Error('expected no Notes: paragraph') +}) + +Deno.test('buildInquiryNotificationEmail includes the product and contact details', () => { + const { subject, html } = buildInquiryNotificationEmail({ + productName: 'Silk Edge Control', + contact: { name: 'Nadia', email: 'nadia@example.com', notes: 'Is this in stock?' }, + }) + assertEquals(subject, 'New inquiry: Silk Edge Control') + assertStringIncludes(html, 'Nadia') + assertStringIncludes(html, 'nadia@example.com') + assertStringIncludes(html, 'Silk Edge Control') + assertStringIncludes(html, 'Is this in stock?') +}) + +Deno.test('buildInquiryNotificationEmail omits the notes paragraph when notes are empty', () => { + const { html } = buildInquiryNotificationEmail({ + productName: 'Braid Oil', + contact: { name: 'Kim', email: 'kim@example.com', notes: '' }, + }) + if (html.includes('Notes:')) throw new Error('expected no Notes: paragraph') +}) diff --git a/supabase/functions/_shared/email.ts b/supabase/functions/_shared/email.ts new file mode 100644 index 0000000..cf8eb89 --- /dev/null +++ b/supabase/functions/_shared/email.ts @@ -0,0 +1,28 @@ +export interface BookingEmailInput { + serviceName: string + date: string + time: string + contact: { name: string; phone: string; email: string; notes: string } +} + +export function buildBookingNotificationEmail(input: BookingEmailInput): { subject: string; html: string } { + const notesLine = input.contact.notes ? `
Notes: ${input.contact.notes}
` : '' + return { + subject: `New booking: ${input.serviceName} on ${input.date}`, + html: `${input.contact.name} booked ${input.serviceName} on ${input.date} at ${input.time}.
` + + `Phone: ${input.contact.phone}
Email: ${input.contact.email}
Notes: ${input.contact.notes}
` : '' + return { + subject: `New inquiry: ${input.productName}`, + html: `${input.contact.name} (${input.contact.email}) asked about ${input.productName}.
${notesLine}`, + } +} diff --git a/supabase/functions/deno.json b/supabase/functions/deno.json new file mode 100644 index 0000000..8ab0875 --- /dev/null +++ b/supabase/functions/deno.json @@ -0,0 +1,5 @@ +{ + "tasks": { + "test": "deno test --allow-none" + } +} diff --git a/supabase/functions/deno.lock b/supabase/functions/deno.lock new file mode 100644 index 0000000..a4437a0 --- /dev/null +++ b/supabase/functions/deno.lock @@ -0,0 +1,18 @@ +{ + "version": "5", + "specifiers": { + "jsr:@std/assert@*": "1.0.19", + "jsr:@std/internal@^1.0.12": "1.0.14" + }, + "jsr": { + "@std/assert@1.0.19": { + "integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/internal@1.0.14": { + "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" + } + } +} diff --git a/vite.config.ts b/vite.config.ts index 32ba018..5bc4af7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -14,6 +14,7 @@ export default defineConfig({ '**/cypress/**', '**/.{idea,git,cache,output,temp}/**', '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', + 'supabase/functions/**', ], }, })