mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-20 16:50:39 +00:00
Simplify test (#145)
* feat: add create-call timeout test * feat: single webhook-test-scaffold and basic auth callhook testcase * cleanup Co-authored-by: Quan Luu <quan.luuhoang8@gmail.com> Co-authored-by: xquanluu <110280845+xquanluu@users.noreply.github.com>
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
const test = require('tape');
|
const test = require('tape');
|
||||||
const { sippUac } = require('./sipp')('test_fs');
|
const { sippUac } = require('./sipp')('test_fs');
|
||||||
const bent = require('bent');
|
const bent = require('bent');
|
||||||
const getJSON = bent('json')
|
|
||||||
const clearModule = require('clear-module');
|
const clearModule = require('clear-module');
|
||||||
const HttpRequestor = require('../lib/utils/http-requestor');
|
const provisionCallHook = require('./utils')
|
||||||
|
const getJSON = bent('json')
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
@@ -24,8 +23,9 @@ test('test create-call timeout', async(t) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await connect(srf);
|
await connect(srf);
|
||||||
let account_sid = '622f62e4-303a-49f2-bbe0-eb1e1714e37a'
|
// GIVEN
|
||||||
const post = bent('http://127.0.0.1:3000/', 'POST', 'json', 201)
|
let account_sid = '622f62e4-303a-49f2-bbe0-eb1e1714e37a';
|
||||||
|
const post = bent('http://127.0.0.1:3000/', 'POST', 'json', 201);
|
||||||
post('v1/createCall', {
|
post('v1/createCall', {
|
||||||
'account_sid':account_sid,
|
'account_sid':account_sid,
|
||||||
'timeout': 1,
|
'timeout': 1,
|
||||||
@@ -37,7 +37,8 @@ test('test create-call timeout', async(t) => {
|
|||||||
"to": {
|
"to": {
|
||||||
"type": "phone",
|
"type": "phone",
|
||||||
"number": "15583084809"
|
"number": "15583084809"
|
||||||
}})
|
}});
|
||||||
|
//THEN
|
||||||
await sippUac('uas-timeout-cancel.xml', '172.38.0.10');
|
await sippUac('uas-timeout-cancel.xml', '172.38.0.10');
|
||||||
disconnect();
|
disconnect();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -47,6 +48,48 @@ test('test create-call timeout', async(t) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function sleep(ms) {
|
test('test create-call call-hook basic authentication', async(t) => {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
clearModule.all();
|
||||||
}
|
const {srf, disconnect} = require('../app');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await connect(srf);
|
||||||
|
// GIVEN
|
||||||
|
let from = 'call_hook_basic_authentication';
|
||||||
|
let account_sid = '622f62e4-303a-49f2-bbe0-eb1e1714e37a';
|
||||||
|
|
||||||
|
const post = bent('http://127.0.0.1:3000/', 'POST', 'json', 201);
|
||||||
|
post('v1/createCall', {
|
||||||
|
'account_sid':account_sid,
|
||||||
|
"call_hook": {
|
||||||
|
"url": "http://127.0.0.1:3100/",
|
||||||
|
"method": "POST",
|
||||||
|
"username": "username",
|
||||||
|
"password": "password"
|
||||||
|
},
|
||||||
|
"from": from,
|
||||||
|
"to": {
|
||||||
|
"type": "phone",
|
||||||
|
"number": "15583084809"
|
||||||
|
}});
|
||||||
|
|
||||||
|
let verbs = [
|
||||||
|
{
|
||||||
|
"verb": "say",
|
||||||
|
"text": "hello"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
provisionCallHook(from, verbs);
|
||||||
|
//THEN
|
||||||
|
await sippUac('uas.xml', '172.38.0.10', from);
|
||||||
|
|
||||||
|
let obj = await getJSON(`http:127.0.0.1:3100/lastRequest/${from}`)
|
||||||
|
t.ok(obj.headers.Authorization = 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=',
|
||||||
|
'create-call: call-hook contains basic authentication header');
|
||||||
|
disconnect();
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`error received: ${err}`);
|
||||||
|
disconnect();
|
||||||
|
t.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ services:
|
|||||||
platform: linux/x86_64
|
platform: linux/x86_64
|
||||||
ports:
|
ports:
|
||||||
- "3360:3306"
|
- "3360:3306"
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "mysqladmin" ,"ping", "-h", "127.0.0.1", "--protocol", "tcp"]
|
test: ["CMD", "mysqladmin" ,"ping", "-h", "127.0.0.1", "--protocol", "tcp"]
|
||||||
@@ -75,10 +75,8 @@ services:
|
|||||||
fs:
|
fs:
|
||||||
ipv4_address: 172.38.0.51
|
ipv4_address: 172.38.0.51
|
||||||
|
|
||||||
webhook-decline:
|
webhook-scaffold:
|
||||||
image: jambonz/webhook-test-scaffold:latest
|
image: jambonz/webhook-test-scaffold:latest
|
||||||
environment:
|
|
||||||
APP_PATH: /tmp/decline.json
|
|
||||||
ports:
|
ports:
|
||||||
- "3100:3000/tcp"
|
- "3100:3000/tcp"
|
||||||
volumes:
|
volumes:
|
||||||
@@ -87,54 +85,6 @@ services:
|
|||||||
fs:
|
fs:
|
||||||
ipv4_address: 172.38.0.60
|
ipv4_address: 172.38.0.60
|
||||||
|
|
||||||
webhook-say:
|
|
||||||
image: jambonz/webhook-test-scaffold:latest
|
|
||||||
environment:
|
|
||||||
APP_PATH: /tmp/say.json
|
|
||||||
ports:
|
|
||||||
- "3101:3000/tcp"
|
|
||||||
volumes:
|
|
||||||
- ./test-apps:/tmp
|
|
||||||
networks:
|
|
||||||
fs:
|
|
||||||
ipv4_address: 172.38.0.61
|
|
||||||
|
|
||||||
webhook-gather:
|
|
||||||
image: jambonz/webhook-test-scaffold:latest
|
|
||||||
environment:
|
|
||||||
APP_PATH: /tmp/gather.json
|
|
||||||
ports:
|
|
||||||
- "3102:3000/tcp"
|
|
||||||
volumes:
|
|
||||||
- ./test-apps:/tmp
|
|
||||||
networks:
|
|
||||||
fs:
|
|
||||||
ipv4_address: 172.38.0.62
|
|
||||||
|
|
||||||
webhook-transcribe:
|
|
||||||
image: jambonz/webhook-test-scaffold:latest
|
|
||||||
environment:
|
|
||||||
APP_PATH: /tmp/transcribe.json
|
|
||||||
ports:
|
|
||||||
- "3103:3000/tcp"
|
|
||||||
volumes:
|
|
||||||
- ./test-apps:/tmp
|
|
||||||
networks:
|
|
||||||
fs:
|
|
||||||
ipv4_address: 172.38.0.63
|
|
||||||
|
|
||||||
webhook-sip-info:
|
|
||||||
image: jambonz/webhook-test-scaffold:latest
|
|
||||||
environment:
|
|
||||||
APP_PATH: /tmp/info.json
|
|
||||||
ports:
|
|
||||||
- "3104:3000/tcp"
|
|
||||||
volumes:
|
|
||||||
- ./test-apps:/tmp
|
|
||||||
networks:
|
|
||||||
fs:
|
|
||||||
ipv4_address: 172.38.0.64
|
|
||||||
|
|
||||||
influxdb:
|
influxdb:
|
||||||
image: influxdb:1.8
|
image: influxdb:1.8
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const { sippUac } = require('./sipp')('test_fs');
|
|||||||
const bent = require('bent');
|
const bent = require('bent');
|
||||||
const getJSON = bent('json')
|
const getJSON = bent('json')
|
||||||
const clearModule = require('clear-module');
|
const clearModule = require('clear-module');
|
||||||
|
const provisionCallHook = require('./utils')
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
@@ -22,9 +23,25 @@ test('\'gather\' and \'transcribe\' tests', async(t) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await connect(srf);
|
await connect(srf);
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10');
|
// GIVEN
|
||||||
let obj = await getJSON('http://127.0.0.1:3102/actionHook');
|
let verbs = [
|
||||||
t.ok(obj.speech.alternatives[0].transcript = 'I\'d like to speak to customer support',
|
{
|
||||||
|
"verb": "gather",
|
||||||
|
"input": ["speech"],
|
||||||
|
"recognizer": {
|
||||||
|
"vendor": "google",
|
||||||
|
"hints": ["customer support", "sales", "human resources", "HR"]
|
||||||
|
},
|
||||||
|
"timeout": 10,
|
||||||
|
"actionHook": "/actionHook"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
let from = "gather_success";
|
||||||
|
provisionCallHook(from, verbs);
|
||||||
|
// THEN
|
||||||
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
|
t.ok(obj.body.speech.alternatives[0].transcript = 'I\'d like to speak to customer support',
|
||||||
'gather: succeeds when using account credentials');
|
'gather: succeeds when using account credentials');
|
||||||
|
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const test = require('tape');
|
const test = require('tape');
|
||||||
const { sippUac } = require('./sipp')('test_fs');
|
const { sippUac } = require('./sipp')('test_fs');
|
||||||
const clearModule = require('clear-module');
|
const clearModule = require('clear-module');
|
||||||
|
const provisionCallHook = require('./utils')
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
@@ -20,9 +21,21 @@ test('\'say\' tests', async(t) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await connect(srf);
|
await connect(srf);
|
||||||
await sippUac('uac-say-account-creds-success.xml', '172.38.0.10');
|
|
||||||
|
// GIVEN
|
||||||
|
const verbs = [
|
||||||
|
{
|
||||||
|
verb: 'say',
|
||||||
|
text: 'hello'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const from = 'say_test_success';
|
||||||
|
provisionCallHook(from, verbs)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
t.pass('say: succeeds when using using account credentials');
|
t.pass('say: succeeds when using using account credentials');
|
||||||
|
|
||||||
disconnect();
|
disconnect();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(`error received: ${err}`);
|
console.log(`error received: ${err}`);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
INVITE sip:16174000000@[remote_ip]:[remote_port] SIP/2.0
|
INVITE sip:16174000000@[remote_ip]:[remote_port] SIP/2.0
|
||||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: <sip:16174000000@[remote_ip]:[remote_port]>
|
To: <sip:16174000000@[remote_ip]:[remote_port]>
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 INVITE
|
CSeq: 1 INVITE
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
ACK sip:16174000000@[remote_ip]:[remote_port] SIP/2.0
|
ACK sip:16174000000@[remote_ip]:[remote_port] SIP/2.0
|
||||||
[last_Via]
|
[last_Via]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: <sip:16174000000@[remote_ip]:[remote_port]>[peer_tag_param]
|
To: <sip:16174000000@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 ACK
|
CSeq: 1 ACK
|
||||||
@@ -53,4 +53,3 @@
|
|||||||
</send>
|
</send>
|
||||||
|
|
||||||
</scenario>
|
</scenario>
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
<send retrans="500">
|
<send retrans="500">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
INVITE sip:16174000003@[remote_ip]:[remote_port] SIP/2.0
|
INVITE sip:[to]@[remote_ip]:[remote_port] SIP/2.0
|
||||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: <sip:16174000003@[remote_ip]:[remote_port]>
|
To: <sip:[to]@[remote_ip]:[remote_port]>
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 INVITE
|
CSeq: 1 INVITE
|
||||||
Contact: sip:sipp@[local_ip]:[local_port]
|
Contact: sip:[from]@[local_ip]:[local_port]
|
||||||
Max-Forwards: 70
|
Max-Forwards: 70
|
||||||
X-Account-Sid: bb845d4b-83a9-4cde-a6e9-50f3743bab3f
|
X-Account-Sid: bb845d4b-83a9-4cde-a6e9-50f3743bab3f
|
||||||
Subject: uac-gather-account-creds-success
|
Subject: uac-gather-account-creds-success
|
||||||
@@ -53,13 +53,13 @@
|
|||||||
<send>
|
<send>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
ACK sip:16174000003@[remote_ip]:[remote_port] SIP/2.0
|
ACK sip:[to]@[remote_ip]:[remote_port] SIP/2.0
|
||||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: 16174000003 <sip:16174000003@[remote_ip]:[remote_port]>[peer_tag_param]
|
To: [to] <sip:[to]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 ACK
|
CSeq: 1 ACK
|
||||||
Contact: sip:sipp@[local_ip]:[local_port]
|
Contact: sip:[from]@[local_ip]:[local_port]
|
||||||
Max-Forwards: 70
|
Max-Forwards: 70
|
||||||
Subject: uac-gather-account-creds-success
|
Subject: uac-gather-account-creds-success
|
||||||
Content-Length: 0
|
Content-Length: 0
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
<send retrans="500">
|
<send retrans="500">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
INVITE sip:16174000006@[remote_ip]:[remote_port] SIP/2.0
|
INVITE sip:[to]@[remote_ip]:[remote_port] SIP/2.0
|
||||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: <sip:16174000006@[remote_ip]:[remote_port]>
|
To: <sip:[to]@[remote_ip]:[remote_port]>
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 INVITE
|
CSeq: 1 INVITE
|
||||||
Contact: sip:sipp@[local_ip]:[local_port]
|
Contact: sip:[from]@[local_ip]:[local_port]
|
||||||
Max-Forwards: 70
|
Max-Forwards: 70
|
||||||
X-Account-Sid: bb845d4b-83a9-4cde-a6e9-50f3743bab3f
|
X-Account-Sid: bb845d4b-83a9-4cde-a6e9-50f3743bab3f
|
||||||
Subject: uac-gather-account-creds-success
|
Subject: uac-gather-account-creds-success
|
||||||
@@ -53,13 +53,13 @@
|
|||||||
<send>
|
<send>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
ACK sip:16174000006@[remote_ip]:[remote_port] SIP/2.0
|
ACK sip:[to]@[remote_ip]:[remote_port] SIP/2.0
|
||||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: 16174000006 <sip:16174000006@[remote_ip]:[remote_port]>[peer_tag_param]
|
To: [to] <sip:[to]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 ACK
|
CSeq: 1 ACK
|
||||||
Contact: sip:sipp@[local_ip]:[local_port]
|
Contact: sip:[from]@[local_ip]:[local_port]
|
||||||
Max-Forwards: 70
|
Max-Forwards: 70
|
||||||
Subject: uac-gather-account-creds-success
|
Subject: uac-gather-account-creds-success
|
||||||
Content-Length: 0
|
Content-Length: 0
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
<send retrans="500">
|
<send retrans="500">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
INVITE sip:16174000001@[remote_ip]:[remote_port] SIP/2.0
|
INVITE sip:[to]@[remote_ip]:[remote_port] SIP/2.0
|
||||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: <sip:16174000001@[remote_ip]:[remote_port]>
|
To: <sip:[to]@[remote_ip]:[remote_port]>
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 INVITE
|
CSeq: 1 INVITE
|
||||||
Contact: sip:sipp@[local_ip]:[local_port]
|
Contact: sip:[from]@[local_ip]:[local_port]
|
||||||
Max-Forwards: 70
|
Max-Forwards: 70
|
||||||
X-Account-Sid: bb845d4b-83a9-4cde-a6e9-50f3743bab3f
|
X-Account-Sid: bb845d4b-83a9-4cde-a6e9-50f3743bab3f
|
||||||
Subject: uac-say
|
Subject: uac-say
|
||||||
@@ -53,13 +53,13 @@
|
|||||||
<send>
|
<send>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
ACK sip:16174000001@[remote_ip]:[remote_port] SIP/2.0
|
ACK sip:[to]@[remote_ip]:[remote_port] SIP/2.0
|
||||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
From: [from] <sip:[from]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||||
To: 16174000001 <sip:16174000001@[remote_ip]:[remote_port]>[peer_tag_param]
|
To: [to] <sip:[to]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||||
Call-ID: [call_id]
|
Call-ID: [call_id]
|
||||||
CSeq: 1 ACK
|
CSeq: 1 ACK
|
||||||
Contact: sip:sipp@[local_ip]:[local_port]
|
Contact: sip:[from]@[local_ip]:[local_port]
|
||||||
Max-Forwards: 70
|
Max-Forwards: 70
|
||||||
Subject: uac-say
|
Subject: uac-say
|
||||||
Content-Length: 0
|
Content-Length: 0
|
||||||
@@ -3,6 +3,7 @@ const { sippUac } = require('./sipp')('test_fs');
|
|||||||
const bent = require('bent');
|
const bent = require('bent');
|
||||||
const getJSON = bent('json')
|
const getJSON = bent('json')
|
||||||
const clearModule = require('clear-module');
|
const clearModule = require('clear-module');
|
||||||
|
const provisionCallHook = require('./utils');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
@@ -22,9 +23,28 @@ test('sending SIP in-dialog requests tests', async(t) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await connect(srf);
|
await connect(srf);
|
||||||
await sippUac('uac-send-info-during-dialog.xml', '172.38.0.10');
|
//GIVEN
|
||||||
const obj = await getJSON('http://127.0.0.1:3104/actionHook');
|
let verbs = [
|
||||||
t.ok(obj.result === 'success' && obj.sip_status === 200, 'successfully sent SIP INFO');
|
{
|
||||||
|
"verb": "say",
|
||||||
|
"text": "hello"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"verb": "sip:request",
|
||||||
|
"method": "info",
|
||||||
|
"headers": {
|
||||||
|
"Content-Type": "application/text"
|
||||||
|
},
|
||||||
|
"body": "here I am ",
|
||||||
|
"actionHook": "/actionHook"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
let from = "sip_indialog_test";
|
||||||
|
provisionCallHook(from, verbs);
|
||||||
|
// THEN
|
||||||
|
await sippUac('uac-send-info-during-dialog.xml', '172.38.0.10', from);
|
||||||
|
const obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
|
t.ok(obj.body.sip_status === 200, 'successfully sent SIP INFO');
|
||||||
|
|
||||||
disconnect();
|
disconnect();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ obj.output = () => {
|
|||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.sippUac = (file, bindAddress) => {
|
obj.sippUac = (file, bindAddress, from='sipp', to='16174000000') => {
|
||||||
const cmd = 'docker';
|
const cmd = 'docker';
|
||||||
const args = [
|
const args = [
|
||||||
'run', '-t', '--rm', '--net', `${network}`,
|
'run', '-t', '--rm', '--net', `${network}`,
|
||||||
@@ -34,7 +34,9 @@ obj.sippUac = (file, bindAddress) => {
|
|||||||
'-sleep', '250ms',
|
'-sleep', '250ms',
|
||||||
'-nostdin',
|
'-nostdin',
|
||||||
'-cid_str', `%u-%p@%s-${idx++}`,
|
'-cid_str', `%u-%p@%s-${idx++}`,
|
||||||
'172.38.0.50'
|
'172.38.0.50',
|
||||||
|
'-key','from', from,
|
||||||
|
'-key','to', to, '-trace_msg'
|
||||||
];
|
];
|
||||||
|
|
||||||
if (bindAddress) args.splice(5, 0, '--ip', bindAddress);
|
if (bindAddress) args.splice(5, 0, '--ip', bindAddress);
|
||||||
|
|||||||
18
test/utils.js
Normal file
18
test/utils.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const bent = require('bent');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* phoneNumber: 16174000000
|
||||||
|
* Hook endpoints http://127.0.0.1:3100/
|
||||||
|
* The function help testcase to register desired jambonz json response for an application call
|
||||||
|
* When a call has From number match the registered hook event, the desired jambonz json will be responded.
|
||||||
|
*/
|
||||||
|
const provisionCallHook = (from, verbs) => {
|
||||||
|
const mapping = {
|
||||||
|
from,
|
||||||
|
data: JSON.stringify(verbs)
|
||||||
|
};
|
||||||
|
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
||||||
|
post('/appMapping', mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = provisionCallHook
|
||||||
@@ -3,47 +3,95 @@ const fs = require('fs');
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const app = express();
|
const app = express();
|
||||||
const listenPort = process.env.HTTP_PORT || 3000;
|
const listenPort = process.env.HTTP_PORT || 3000;
|
||||||
let lastAction, lastEvent;
|
let json_mapping = new Map();
|
||||||
|
let hook_mapping = new Map();
|
||||||
assert.ok(process.env.APP_PATH, 'env var APP_PATH is required');
|
|
||||||
|
|
||||||
app.listen(listenPort, () => {
|
app.listen(listenPort, () => {
|
||||||
console.log(`sample jambones app server listening on ${listenPort}`);
|
console.log(`sample jambones app server listening on ${listenPort}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
const applicationData = JSON.parse(fs.readFileSync(process.env.APP_PATH));
|
|
||||||
app.use(express.urlencoded({ extended: true }));
|
app.use(express.urlencoded({ extended: true }));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Markup language
|
||||||
|
*/
|
||||||
|
|
||||||
app.all('/', (req, res) => {
|
app.all('/', (req, res) => {
|
||||||
console.log(applicationData, `${req.method} /`);
|
console.log(req.body, 'POST /');
|
||||||
return res.json(applicationData);
|
const key = req.body.from
|
||||||
|
if (!json_mapping.has(key)) return res.sendStatus(404);
|
||||||
|
const retData = JSON.parse(json_mapping.get(key));
|
||||||
|
console.log(retData, `${req.method} /`);
|
||||||
|
addRequestToMap(key, req, hook_mapping);
|
||||||
|
return res.json(retData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.post('/appMapping', (req, res) => {
|
||||||
|
console.log(req.body, 'POST /appMapping');
|
||||||
|
json_mapping.set(req.body.from, req.body.data);
|
||||||
|
return res.sendStatus(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status Callback
|
||||||
|
*/
|
||||||
app.post('/callStatus', (req, res) => {
|
app.post('/callStatus', (req, res) => {
|
||||||
console.log({payload: req.body}, 'POST /callStatus');
|
console.log({payload: req.body}, 'POST /callStatus');
|
||||||
|
let key = req.body.from + "_callStatus"
|
||||||
|
addRequestToMap(key, req, hook_mapping);
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
/*
|
||||||
|
* action Hook
|
||||||
|
*/
|
||||||
app.post('/actionHook', (req, res) => {
|
app.post('/actionHook', (req, res) => {
|
||||||
console.log({payload: req.body}, 'POST /actionHook');
|
console.log({payload: req.body}, 'POST /actionHook');
|
||||||
lastAction = req.body;
|
let key = req.body.from + "_actionHook"
|
||||||
|
addRequestToMap(key, req, hook_mapping);
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/actionHook', (req, res) => {
|
// Fetch Requests
|
||||||
console.log({payload: lastAction}, 'GET /actionHook');
|
app.get('/requests/:key', (req, res) => {
|
||||||
return res.json(lastAction);
|
let key = req.params.key;
|
||||||
});
|
if (hook_mapping.has(key)) {
|
||||||
|
return res.json(hook_mapping.get(key));
|
||||||
|
} else {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
app.post('/eventHook', (req, res) => {
|
})
|
||||||
console.log({payload: req.body}, 'POST /eventHook');
|
|
||||||
lastEvent = req.body;
|
|
||||||
return res.sendStatus(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/eventHook', (req, res) => {
|
app.get('/lastRequest/:key', (req, res) => {
|
||||||
console.log({payload: lastEvent}, 'GET /eventHook');
|
let key = req.params.key;
|
||||||
return res.json(lastEvent);
|
if (hook_mapping.has(key)) {
|
||||||
});
|
let requests = hook_mapping.get(key);
|
||||||
|
return res.json(requests[requests.length - 1]);
|
||||||
|
} else {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* private function
|
||||||
|
*/
|
||||||
|
|
||||||
|
function addRequestToMap(key, req, map) {
|
||||||
|
let headers = new Map()
|
||||||
|
for(let i = 0; i < req.rawHeaders.length; i++) {
|
||||||
|
if (i % 2 === 0) {
|
||||||
|
headers.set(req.rawHeaders[i], req.rawHeaders[i + 1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let request = {
|
||||||
|
'url': req.url,
|
||||||
|
'headers': Object.fromEntries(headers),
|
||||||
|
'body': req.body
|
||||||
|
}
|
||||||
|
if (map.has(key)) {
|
||||||
|
map.get(key).push(request);
|
||||||
|
} else {
|
||||||
|
map.set(key, [request]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,10 +17,25 @@ function connect(connectable) {
|
|||||||
test('basic webhook tests', async(t) => {
|
test('basic webhook tests', async(t) => {
|
||||||
clearModule.all();
|
clearModule.all();
|
||||||
const {srf, disconnect} = require('../app');
|
const {srf, disconnect} = require('../app');
|
||||||
|
const provisionCallHook = require('./utils')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await connect(srf);
|
await connect(srf);
|
||||||
await sippUac('uac-expect-603.xml', '172.38.0.10');
|
const verbs = [
|
||||||
|
{
|
||||||
|
verb: 'sip:decline',
|
||||||
|
status: 603,
|
||||||
|
reason: 'Gone Fishin',
|
||||||
|
headers: {
|
||||||
|
'Retry-After': 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const from = 'sip_decline_test_success';
|
||||||
|
provisionCallHook(from, verbs)
|
||||||
|
|
||||||
|
await sippUac('uac-expect-603.xml', '172.38.0.10', from);
|
||||||
t.pass('webhook successfully declines call');
|
t.pass('webhook successfully declines call');
|
||||||
|
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|||||||
Reference in New Issue
Block a user