59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
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')
|
|
})
|
|
})
|