You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sims-hq/apps/hq/test/sms-gateway.test.ts

53 lines
2.2 KiB
TypeScript

// apps/hq/test/sms-gateway.test.ts — D28: parse the SMS gateway's balance response.
import { describe, it, expect } from 'vitest'
import { parseBalanceResponse, balanceUrl, assertSafeGatewayUrl } from '../src/sms-gateway'
describe('parseBalanceResponse (D28)', () => {
it('reads the balance from a success line (code|STATUS|balance)', () => {
const r = parseBalanceResponse('001|SUCCESS|8200')
expect(r.ok).toBe(true)
expect(r.balance).toBe(8200)
})
it('tolerates commas/spaces and a plain-number body', () => {
expect(parseBalanceResponse('000|OK|1,25,000').balance).toBe(125000)
expect(parseBalanceResponse('8200').balance).toBe(8200)
})
it('flags the real error response as failed with its message', () => {
const r = parseBalanceResponse('002|ERROR|Invalid User Id / Password')
expect(r.ok).toBe(false)
expect(r.balance).toBeNull()
expect(r.message).toMatch(/Invalid User Id/)
})
it('fails cleanly on empty or unreadable text (never a wrong number)', () => {
expect(parseBalanceResponse('').ok).toBe(false)
expect(parseBalanceResponse('welcome to the panel').ok).toBe(false)
})
})
describe('balanceUrl (D28)', () => {
it('substitutes credentials into the configured base URL', () => {
const u = balanceUrl('http://164.52.195.161/API/BalAlert.aspx', 'bankuser', 'p@ss w/special')
expect(u).toContain('uname=bankuser')
expect(u).toContain('pass=p%40ss+w%2Fspecial') // URL-encoded
})
})
describe('assertSafeGatewayUrl (D28 SSRF guard)', () => {
it('allows the vendor panel and other public hosts', () => {
expect(() => assertSafeGatewayUrl('http://164.52.195.161/API/BalAlert.aspx')).not.toThrow()
expect(() => assertSafeGatewayUrl('https://sms.vendor.example/bal')).not.toThrow()
})
it('blocks loopback, link-local metadata, and private ranges', () => {
for (const bad of [
'http://127.0.0.1/x', 'http://localhost/x', 'http://169.254.169.254/latest/meta-data',
'http://10.0.0.5/x', 'http://192.168.1.5/x', 'http://172.16.0.1/x', 'http://[::1]/x',
'http://box.internal/x', 'ftp://164.52.195.161/x',
]) {
expect(() => assertSafeGatewayUrl(bad), bad).toThrow()
}
})
})