Files
adam-acs/tests/unit/services/references/wassup_provider.spec.ts
T
Kevin L'Hereec e857b4fbe7 feat: reference providers system with Wassup integration
- Pluggable multi-provider architecture (ReferenceEngine)
- Wassup provider implementation (HTTP GET + X_WASSUP_USER_IP)
- Auto-resolve references on Inform (BOOT/BOOTSTRAP events)
- References displayed in device Identity card
- REST API: GET/POST references per device
- Config via config/references.json
- Fix event extraction for single EventStruct and numeric EventCodes
- Mock Wassup provisioned by home-device-simulator on device creation
2026-06-02 15:52:16 +02:00

120 lines
3.9 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { WassupProvider } from '../../../../app/services/references/providers/wassup_provider.js'
import type { ProviderConfig } from '../../../../app/services/references/types.js'
import type { DeviceRecord } from '../../../../app/domain/device/device_record.js'
import { DeviceId } from '../../../../app/domain/device/device_id.js'
import { createServer, type Server } from 'node:http'
function makeDevice(): DeviceRecord {
return {
identifier: 'test-device-001',
deviceId: new DeviceId('TestCorp', 'AABBCC', 'TestBox', 'SERIAL001'),
properties: [],
parameters: [],
}
}
function makeConfig(overrides: Partial<ProviderConfig> = {}): ProviderConfig {
return {
name: 'wassup',
type: 'wassup',
enabled: true,
url: 'http://localhost:19876',
timeout: 2000,
trigger: ['BOOT'],
resolveBy: 'ip',
options: { service: 'KRMSCO', requestedProperties: ['sai', 'spr'] },
...overrides,
}
}
describe('WassupProvider', () => {
let server: Server
let responseBody: string
let responseStatus: number
beforeEach(() => {
responseBody = 'X_WASSUP_STATUS=OK\nX_WASSUP_SAI=123456789\nX_WASSUP_SPR=FR\n'
responseStatus = 200
server = createServer((_req, res) => {
res.writeHead(responseStatus, { 'Content-Type': 'text/plain' })
res.end(responseBody)
})
server.listen(19876)
})
afterEach(() => {
server.close()
})
it('resolves successfully with OK status', async () => {
const provider = new WassupProvider(makeConfig())
const result = await provider.resolve(makeDevice(), { events: [], remoteIp: '10.0.0.1', headers: {} })
expect(result).not.toBeNull()
expect(result!.status).toBe('ok')
expect(result!.provider).toBe('wassup')
expect(result!.resolvedBy).toBe('ip:10.0.0.1')
expect(result!.properties.sai).toBe('123456789')
expect(result!.properties.spr).toBe('FR')
})
it('returns unknown when user not found', async () => {
responseBody = 'X_WASSUP_STATUS=UNKNOWN_USER\nX_WASSUP_ERROR=ICS_RESULT_LDAP_ERROR\n'
const provider = new WassupProvider(makeConfig())
const result = await provider.resolve(makeDevice(), { events: [], remoteIp: '10.0.0.99', headers: {} })
expect(result).not.toBeNull()
expect(result!.status).toBe('unknown')
expect(result!.properties).toEqual({})
})
it('returns error on HTTP failure', async () => {
responseStatus = 500
responseBody = 'Internal Server Error'
const provider = new WassupProvider(makeConfig())
const result = await provider.resolve(makeDevice(), { events: [], remoteIp: '10.0.0.1', headers: {} })
expect(result).not.toBeNull()
expect(result!.status).toBe('error')
expect(result!.error).toContain('HTTP 500')
})
it('returns error on timeout', async () => {
server.close()
server = createServer((_req, res) => {
// Never respond — simulate timeout
setTimeout(() => {
res.writeHead(200)
res.end('X_WASSUP_STATUS=OK\n')
}, 5000)
})
server.listen(19876)
const provider = new WassupProvider(makeConfig({ timeout: 100 }))
const result = await provider.resolve(makeDevice(), { events: [], remoteIp: '10.0.0.1', headers: {} })
expect(result).not.toBeNull()
expect(result!.status).toBe('error')
expect(result!.error).toBe('Timeout')
})
it('returns null when no IP available', async () => {
const provider = new WassupProvider(makeConfig())
const result = await provider.resolve(makeDevice(), { events: [], remoteIp: '', headers: {} })
expect(result).toBeNull()
})
it('resolves by serialNumber when configured', async () => {
const provider = new WassupProvider(makeConfig({ resolveBy: 'serialNumber' }))
const result = await provider.resolve(makeDevice(), { events: [], remoteIp: '', headers: {} })
expect(result).not.toBeNull()
expect(result!.resolvedBy).toBe('serialNumber:SERIAL001')
})
})