import { describe, it, expect, vi, beforeEach } from 'vitest' import { sendWhatsAppMessage } from '@/lib/notifications/whatsapp' const fetchMock = vi.fn() vi.stubGlobal('fetch', fetchMock) describe('sendWhatsAppMessage', () => { beforeEach(() => fetchMock.mockClear()) it('posts to Meta Graph API with correct template structure', async () => { fetchMock.mockResolvedValueOnce( new Response('{"messages":[{"id":"wamid.abc"}]}', { status: 200 }) ) await sendWhatsAppMessage( '60123456789', 'ims_incident_alert', ['SETIA-202407-0001', 'injury', 'Warehouse A'], 'test-phone-id', 'test-token' ) expect(fetchMock).toHaveBeenCalledOnce() const [url, opts] = fetchMock.mock.calls[0] expect(url).toBe('https://graph.facebook.com/v19.0/test-phone-id/messages') expect(opts.method).toBe('POST') expect(opts.headers['Authorization']).toBe('Bearer test-token') const body = JSON.parse(opts.body) expect(body.messaging_product).toBe('whatsapp') expect(body.to).toBe('60123456789') expect(body.type).toBe('template') expect(body.template.name).toBe('ims_incident_alert') expect(body.template.language.code).toBe('en_US') expect(body.template.components[0].parameters).toHaveLength(3) expect(body.template.components[0].parameters[0]).toEqual({ type: 'text', text: 'SETIA-202407-0001' }) }) it('throws on non-2xx response', async () => { fetchMock.mockResolvedValueOnce( new Response('{"error":{"message":"Invalid token"}}', { status: 400 }) ) await expect( sendWhatsAppMessage('60123456789', 'ims_incident_alert', ['a'], 'pid', 'tok') ).rejects.toThrow('WhatsApp API error: 400') }) it('returns immediately without calling fetch when phoneNumber is empty', async () => { await sendWhatsAppMessage('', 'ims_incident_alert', ['a'], 'pid', 'tok') expect(fetchMock).not.toHaveBeenCalled() }) it('sanitizes phone number — strips spaces, dashes, and plus sign', async () => { fetchMock.mockResolvedValueOnce( new Response('{"messages":[{"id":"x"}]}', { status: 200 }) ) await sendWhatsAppMessage('+60 12-345 6789', 'ims_incident_alert', ['a'], 'pid', 'tok') const body = JSON.parse(fetchMock.mock.calls[0][1].body) expect(body.to).toBe('60123456789') }) })