sendi/tests/unit/phone.test.ts
jmcqueen d0a0dda2b8 Initial commit: Sendi 2.0 SMS gateway (Webex + Twilio)
Sendi is a Webex to Twilio SMS gateway written in TypeScript that runs
directly on Node 22.18+ via native type-stripping (no bundler/transpiler).
Each Webex space represents one external SMS contact; inbound MMS is
proxied both ways, with delivery-status cards for outbound sends.

Highlights:
- Express 5 HTTP surface for Twilio /sms and /callback (signature-validated)
- webex-node-bot-framework in websocket transport mode for bot control plane
- Prisma 6 + SQLite via better-sqlite3 driver adapter
- Zod-validated env with fail-fast startup and pino secret redaction
- Pino logging: pretty in dev, structured JSON in prod
- 13 vitest unit tests (phone normalization, Twilio signature validation,
  card action dispatch)
- Native --require preload patches Node 22's read-only globalThis.navigator
  so @webex/internal-media-core (transitive) can load

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 11:10:44 -04:00

51 lines
1.7 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { toE164, isE164, formatForDisplay } from '../../src/lib/phone.ts';
describe('toE164', () => {
it('normalizes 10-digit NANP', () => {
expect(toE164('289-206-7080')).toBe('+12892067080');
expect(toE164('(289) 206-7080')).toBe('+12892067080');
expect(toE164('289.206.7080')).toBe('+12892067080');
expect(toE164('2892067080')).toBe('+12892067080');
});
it('normalizes 11-digit NANP starting with 1', () => {
expect(toE164('12892067080')).toBe('+12892067080');
expect(toE164('1-289-206-7080')).toBe('+12892067080');
});
it('preserves +-prefixed E.164', () => {
expect(toE164('+442071838750')).toBe('+442071838750');
expect(toE164('+1 289 206 7080')).toBe('+12892067080');
});
it('throws on inputs that cannot be normalized', () => {
expect(() => toE164('abc')).toThrow();
expect(() => toE164('123')).toThrow();
expect(() => toE164('')).toThrow();
});
});
describe('isE164', () => {
it('recognizes valid E.164', () => {
expect(isE164('+12892067080')).toBe(true);
expect(isE164('+442071838750')).toBe(true);
});
it('rejects invalid inputs', () => {
expect(isE164('2892067080')).toBe(false);
expect(isE164('+0123456789')).toBe(false);
expect(isE164(undefined)).toBe(false);
expect(isE164(12345)).toBe(false);
});
});
describe('formatForDisplay', () => {
it('formats NANP numbers', () => {
expect(formatForDisplay('+12892067080')).toBe('(289) 206-7080');
});
it('returns non-NANP numbers unchanged', () => {
expect(formatForDisplay('+442071838750')).toBe('+442071838750');
});
});