From 1f4b175fc8e9c77672a056269a3a71b8d5dbf526 Mon Sep 17 00:00:00 2001 From: Dave Horton Date: Wed, 16 Jun 2021 16:27:18 -0400 Subject: [PATCH] added queue_event_hook at the account level for webhooks on queue events (e.g. members arriving or leaving) --- db/jambones-sql.sql | 55 +++++++++++++----------- db/jambones.sqs | 34 +++++++++++---- lib/db/index.js | 4 +- lib/db/pool.js | 10 +++++ lib/models/account.js | 21 +++++++-- lib/routes/api/accounts.js | 88 +++++++++++++++++++++++++------------- lib/swagger/swagger.yaml | 6 +++ package.json | 12 ++---- test/accounts.js | 12 ++++-- test/applications.js | 2 +- test/auth.js | 2 +- test/create-test-db.js | 2 +- test/docker_start.js | 3 +- test/docker_stop.js | 2 +- test/ms-teams.js | 2 +- test/phone-numbers.js | 2 +- test/remove-test-db.js | 2 +- test/sbcs.js | 2 +- test/service-providers.js | 2 +- test/sip-gateways.js | 2 +- test/voip-carriers.js | 2 +- 21 files changed, 173 insertions(+), 94 deletions(-) create mode 100644 lib/db/pool.js diff --git a/db/jambones-sql.sql b/db/jambones-sql.sql index 3f7a2f7..2edb35b 100644 --- a/db/jambones-sql.sql +++ b/db/jambones-sql.sql @@ -22,10 +22,10 @@ DROP TABLE IF EXISTS sip_gateways; DROP TABLE IF EXISTS voip_carriers; -DROP TABLE IF EXISTS accounts; - DROP TABLE IF EXISTS applications; +DROP TABLE IF EXISTS accounts; + DROP TABLE IF EXISTS service_providers; DROP TABLE IF EXISTS webhooks; @@ -150,6 +150,21 @@ priority INTEGER NOT NULL DEFAULT 0 COMMENT 'lower priority carriers are attempt PRIMARY KEY (lcr_carrier_set_entry_sid) ) COMMENT='An entry in the LCR routing list'; +CREATE TABLE accounts +( +account_sid CHAR(36) NOT NULL UNIQUE , +name VARCHAR(64) NOT NULL, +sip_realm VARCHAR(132) UNIQUE COMMENT 'sip domain that will be used for devices registering under this account', +service_provider_sid CHAR(36) NOT NULL COMMENT 'service provider that owns the customer relationship with this account', +registration_hook_sid CHAR(36) COMMENT 'webhook to call when devices underr this account attempt to register', +queue_event_hook_sid CHAR(36) COMMENT 'webhook to call when members enter or leave a queue created by this account.', +device_calling_application_sid CHAR(36) COMMENT 'application to use for outbound calling from an account', +is_active BOOLEAN NOT NULL DEFAULT true, +webhook_secret VARCHAR(36), +disable_cdrs BOOLEAN NOT NULL DEFAULT 0, +PRIMARY KEY (account_sid) +) COMMENT='An enterprise that uses the platform for comm services'; + CREATE TABLE applications ( application_sid CHAR(36) NOT NULL UNIQUE , @@ -177,20 +192,6 @@ ms_teams_fqdn VARCHAR(255), PRIMARY KEY (service_provider_sid) ) COMMENT='A partition of the platform used by one service provider'; -CREATE TABLE accounts -( -account_sid CHAR(36) NOT NULL UNIQUE , -name VARCHAR(64) NOT NULL, -sip_realm VARCHAR(132) UNIQUE COMMENT 'sip domain that will be used for devices registering under this account', -service_provider_sid CHAR(36) NOT NULL COMMENT 'service provider that owns the customer relationship with this account', -registration_hook_sid CHAR(36) COMMENT 'webhook to call when devices underr this account attempt to register', -device_calling_application_sid CHAR(36) COMMENT 'application to use for outbound calling from an account', -is_active BOOLEAN NOT NULL DEFAULT true, -webhook_secret VARCHAR(36), -disable_cdrs BOOLEAN NOT NULL DEFAULT 0, -PRIMARY KEY (account_sid) -) COMMENT='An enterprise that uses the platform for comm services'; - CREATE INDEX call_route_sid_idx ON call_routes (call_route_sid); ALTER TABLE call_routes ADD FOREIGN KEY account_sid_idxfk (account_sid) REFERENCES accounts (account_sid); @@ -242,6 +243,17 @@ ALTER TABLE lcr_carrier_set_entry ADD FOREIGN KEY lcr_route_sid_idxfk (lcr_route ALTER TABLE lcr_carrier_set_entry ADD FOREIGN KEY voip_carrier_sid_idxfk_2 (voip_carrier_sid) REFERENCES voip_carriers (voip_carrier_sid); +CREATE INDEX account_sid_idx ON accounts (account_sid); +CREATE INDEX sip_realm_idx ON accounts (sip_realm); +CREATE INDEX service_provider_sid_idx ON accounts (service_provider_sid); +ALTER TABLE accounts ADD FOREIGN KEY service_provider_sid_idxfk_3 (service_provider_sid) REFERENCES service_providers (service_provider_sid); + +ALTER TABLE accounts ADD FOREIGN KEY registration_hook_sid_idxfk (registration_hook_sid) REFERENCES webhooks (webhook_sid); + +ALTER TABLE accounts ADD FOREIGN KEY queue_event_hook_sid_idxfk (queue_event_hook_sid) REFERENCES webhooks (webhook_sid); + +ALTER TABLE accounts ADD FOREIGN KEY device_calling_application_sid_idxfk (device_calling_application_sid) REFERENCES applications (application_sid); + CREATE UNIQUE INDEX applications_idx_name ON applications (account_sid,name); CREATE INDEX application_sid_idx ON applications (application_sid); @@ -257,15 +269,6 @@ ALTER TABLE applications ADD FOREIGN KEY messaging_hook_sid_idxfk (messaging_hoo CREATE INDEX service_provider_sid_idx ON service_providers (service_provider_sid); CREATE INDEX name_idx ON service_providers (name); CREATE INDEX root_domain_idx ON service_providers (root_domain); -ALTER TABLE service_providers ADD FOREIGN KEY registration_hook_sid_idxfk (registration_hook_sid) REFERENCES webhooks (webhook_sid); - -CREATE INDEX account_sid_idx ON accounts (account_sid); -CREATE INDEX sip_realm_idx ON accounts (sip_realm); -CREATE INDEX service_provider_sid_idx ON accounts (service_provider_sid); -ALTER TABLE accounts ADD FOREIGN KEY service_provider_sid_idxfk_3 (service_provider_sid) REFERENCES service_providers (service_provider_sid); - -ALTER TABLE accounts ADD FOREIGN KEY registration_hook_sid_idxfk_1 (registration_hook_sid) REFERENCES webhooks (webhook_sid); - -ALTER TABLE accounts ADD FOREIGN KEY device_calling_application_sid_idxfk (device_calling_application_sid) REFERENCES applications (application_sid); +ALTER TABLE service_providers ADD FOREIGN KEY registration_hook_sid_idxfk_1 (registration_hook_sid) REFERENCES webhooks (webhook_sid); SET FOREIGN_KEY_CHECKS=1; diff --git a/db/jambones.sqs b/db/jambones.sqs index 97f83a1..1f6c7be 100644 --- a/db/jambones.sqs +++ b/db/jambones.sqs @@ -260,7 +260,7 @@ 376.00 - 254.00 + 268.00 120.00 10 @@ -529,7 +529,7 @@ 380.00 - 200.00 + 220.00 4 @@ -583,13 +583,29 @@ webhooks - 4 - 2 + 2 + 1 + + + + + webhook_sid + webhooks + + + 2 + 1 + + + + + + @@ -1145,17 +1161,17 @@ - + - - - + + + - + diff --git a/lib/db/index.js b/lib/db/index.js index 9d77afc..93f4546 100644 --- a/lib/db/index.js +++ b/lib/db/index.js @@ -1,5 +1,7 @@ const getMysqlConnection = require('./mysql'); +const promisePool = require('./pool'); module.exports = { - getMysqlConnection + getMysqlConnection, + promisePool }; diff --git a/lib/db/pool.js b/lib/db/pool.js new file mode 100644 index 0000000..5cc3feb --- /dev/null +++ b/lib/db/pool.js @@ -0,0 +1,10 @@ +const mysql = require('mysql2'); +const pool = mysql.createPool({ + host: process.env.JAMBONES_MYSQL_HOST, + port: process.env.JAMBONES_MYSQL_PORT || 3306, + user: process.env.JAMBONES_MYSQL_USER, + password: process.env.JAMBONES_MYSQL_PASSWORD, + database: process.env.JAMBONES_MYSQL_DATABASE, + connectionLimit: process.env.JAMBONES_MYSQL_CONNECTION_LIMIT || 10 +}); +module.exports = pool.promise(); diff --git a/lib/models/account.js b/lib/models/account.js index db52e60..c274462 100644 --- a/lib/models/account.js +++ b/lib/models/account.js @@ -3,17 +3,28 @@ const {getMysqlConnection} = require('../db'); const retrieveSql = `SELECT * from accounts acc LEFT JOIN webhooks AS rh -ON acc.registration_hook_sid = rh.webhook_sid`; +ON acc.registration_hook_sid = rh.webhook_sid +LEFT JOIN webhooks AS qh +ON acc.queue_event_hook_sid = qh.webhook_sid`; + function transmogrifyResults(results) { return results.map((row) => { - const obj = row.acc; + let obj = row.acc; if (row.rh && Object.keys(row.rh).length && row.rh.url !== null) { - Object.assign(obj, {registration_hook: row.rh}); + obj = {...obj, registration_hook: row.rh}; delete obj.registration_hook.webhook_sid; } else obj.registration_hook = null; + + if (row.qh && Object.keys(row.qh).length && row.qh.url !== null) { + obj = {...obj, queue_event_hook: row.qh}; + delete obj.queue_event_hook.webhook_sid; + } + else obj.queue_event_hook = null; + delete obj.registration_hook_sid; + delete obj.queue_event_hook_sid; return obj; }); } @@ -100,6 +111,10 @@ Account.fields = [ name: 'registration_hook_sid', type: 'string', }, + { + name: 'queue_event_hook_sid', + type: 'string', + }, { name: 'device_calling_application_sid', type: 'string', diff --git a/lib/routes/api/accounts.js b/lib/routes/api/accounts.js index 0c0a45f..c6fef8e 100644 --- a/lib/routes/api/accounts.js +++ b/lib/routes/api/accounts.js @@ -6,14 +6,9 @@ const Webhook = require('../../models/webhook'); const ApiKey = require('../../models/api-key'); const ServiceProvider = require('../../models/service-provider'); const uuidv4 = require('uuid/v4'); -const decorate = require('./decorate'); const snakeCase = require('../../utils/snake-case'); const sysError = require('./error'); -const preconditions = { - 'add': validateAdd, - 'update': validateUpdate, - 'delete': validateDelete -}; +const {promisePool} = require('../../db'); let idx = 0; function coerceNumbers(callInfo) { @@ -207,6 +202,9 @@ async function validateAdd(req) { if (req.body.registration_hook && typeof req.body.registration_hook !== 'object') { throw new DbErrorBadRequest('\'registration_hook\' must be an object when adding an account'); } + if (req.body.queue_event_hook && typeof req.body.queue_event_hook !== 'object') { + throw new DbErrorBadRequest('\'queue_event_hook\' must be an object when adding an account'); + } } async function validateUpdate(req, sid) { if (req.user.hasAccountAuth && req.user.account_sid !== sid) { @@ -235,7 +233,32 @@ async function validateDelete(req, sid) { } } -decorate(router, Account, ['delete'], preconditions); +/* delete */ +router.delete('/:sid', async(req, res) => { + const sid = req.params.sid; + const logger = req.app.locals.logger; + try { + await validateDelete(req, sid); + + /* delete associated webhooks */ + const webhooks = []; + const [results] = await promisePool.query('SELECT * FROM accounts where account_sid = ?', sid); + if (results.length) { + if (results[0].registration_hook_sid) webhooks.push(results[0].registration_hook_sid); + if (results[0].queue_event_hook_sid) webhooks.push(results[0].queue_event_hook_sid); + } + await Account.remove(sid); + + for (const wh of webhooks) { + promisePool.execute('DELETE from webhooks where webhook_sid = ?', [wh]) + .catch((err) => logger.info({err, webhooks}, 'DELETE /Accounts Error deleting webhooks')); + } + + res.sendStatus(204); + } catch (err) { + sysError(logger, res, err); + } +}); /* add */ router.post('/', async(req, res) => { @@ -245,7 +268,7 @@ router.post('/', async(req, res) => { // create webhooks if provided const obj = Object.assign({}, req.body); - for (const prop of ['registration_hook']) { + for (const prop of ['registration_hook', 'queue_event_hook']) { if (obj[prop]) { obj[`${prop}_sid`] = await Webhook.make(obj[prop]); delete obj[prop]; @@ -295,43 +318,48 @@ router.put('/:sid', async(req, res) => { // create webhooks if provided const obj = Object.assign({}, req.body); - if (null !== obj.registration_hook) { - for (const prop of ['registration_hook']) { - if (prop in obj && Object.keys(obj[prop]).length) { - if ('webhook_sid' in obj[prop]) { - const sid = obj[prop]['webhook_sid']; - delete obj[prop]['webhook_sid']; - await Webhook.update(sid, obj[prop]); - } - else { - const sid = await Webhook.make(obj[prop]); - obj[`${prop}_sid`] = sid; - } + for (const prop of ['registration_hook', 'queue_event_hook']) { + if (prop in obj && Object.keys(obj[prop]).length) { + if ('webhook_sid' in obj[prop]) { + const sid = obj[prop]['webhook_sid']; + delete obj[prop]['webhook_sid']; + await Webhook.update(sid, obj[prop]); } else { - obj[`${prop}_sid`] = null; + const sid = await Webhook.make(obj[prop]); + obj[`${prop}_sid`] = sid; } - delete obj[prop]; } + delete obj[prop]; } - await validateUpdate(req, sid); if (Object.keys(obj).length) { - let orphanedHook; - if (null === obj.registration_hook) { + const orphanedHooks = []; + if (null === obj.registration_hook || null == obj.queue_event_hook) { const results = await Account.retrieve(sid); - if (results.length && results[0].registration_hook_sid) orphanedHook = results[0].registration_hook_sid; - obj.registration_hook_sid = null; - delete obj.registration_hook; + if (results.length) { + if (results[0].registration_hook_sid) orphanedHooks.push(results[0].registration_hook_sid); + if (results[0].queue_event_hook_sid) orphanedHooks.push(results[0].queue_event_hook_sid); + } + if (null === obj.registration_hook) { + obj.registration_hook_sid = null; + delete obj.registration_hook; + } + if (null === obj.queue_event_hook) { + obj.queue_event_hook_sid = null; + delete obj.queue_event_hook; + } } logger.info({obj}, `about to update Account ${sid}`); const rowsAffected = await Account.update(sid, obj); if (rowsAffected === 0) { return res.status(404).end(); } - if (orphanedHook) { - await Webhook.remove(orphanedHook); + if (orphanedHooks.length) { + for (const sid in orphanedHooks) { + await Webhook.remove(sid); + } } } diff --git a/lib/swagger/swagger.yaml b/lib/swagger/swagger.yaml index a38069f..8d06716 100644 --- a/lib/swagger/swagger.yaml +++ b/lib/swagger/swagger.yaml @@ -981,6 +981,9 @@ paths: registration_hook: $ref: '#/components/schemas/Webhook' description: authentication webhook for registration + queue_event_hook: + $ref: '#/components/schemas/Webhook' + description: webhook for queue events service_provider_sid: type: string format: uuid @@ -1744,6 +1747,9 @@ components: registration_hook: $ref: '#/components/schemas/Webhook' description: authentication webhook for registration + queue_event_hook: + $ref: '#/components/schemas/Webhook' + description: webhook for queue events device_calling_application_sid: type: string format: uuid diff --git a/package.json b/package.json index 4bca457..30b5aa7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "app.js", "scripts": { "start": "node app.js", - "test": "NODE_ENV=test JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_MYSQL_PORT=3360 JAMBONES_REDIS_HOST=localhost JAMBONES_LOGLEVEL=error JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/ | ./node_modules/.bin/tap-spec", + "test": "NODE_ENV=test JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_MYSQL_PORT=3360 JAMBONES_REDIS_HOST=localhost JAMBONES_LOGLEVEL=error JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/ ", "integration-test": "NODE_ENV=test JAMBONES_TIME_SERIES_HOST=127.0.0.1 AWS_REGION='us-east-1' JAMBONES_CURRENCY=USD JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=debug JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/serve-integration.js", "coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test", "jslint": "eslint app.js lib" @@ -16,11 +16,8 @@ "url": "https://github.com/jambonz/jambonz-api-server.git" }, "dependencies": { - "@jambonz/db-helpers": "^0.5.5", - "@jambonz/messaging-382com": "0.0.2", - "@jambonz/messaging-peerless": "0.0.9", - "@jambonz/messaging-simwood": "0.0.4", - "@jambonz/realtimedb-helpers": "0.2.19", + "@jambonz/db-helpers": "^0.6.11", + "@jambonz/realtimedb-helpers": "^0.4.1", "cors": "^2.8.5", "express": "^4.17.1", "mysql2": "^2.2.5", @@ -34,11 +31,10 @@ "yamljs": "^0.3.0" }, "devDependencies": { - "blue-tape": "^1.0.0", "eslint": "^7.15.0", "eslint-plugin-promise": "^4.2.1", "nyc": "^15.1.0", "request-promise-native": "^1.0.9", - "tap-spec": "^5.0.0" + "tape": "^5.2.2" } } diff --git a/test/accounts.js b/test/accounts.js index 5084bdc..06fd382 100644 --- a/test/accounts.js +++ b/test/accounts.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ @@ -36,6 +36,10 @@ test('account tests', async(t) => { registration_hook: { url: 'http://example.com/reg', method: 'get' + }, + queue_event_hook: { + url: 'http://example.com/q', + method: 'post' } } }); @@ -68,9 +72,10 @@ test('account tests', async(t) => { json: true, }); let regHook = result[0].registration_hook; + let qHook = result[0].queue_event_hook; t.ok(result.length === 1 && - Object.keys(regHook).length == 4, 'successfully queried all accounts'); - + Object.keys(regHook).length == 4 && Object.keys(qHook).length == 4, 'successfully queried all accounts'); + /* query one accounts */ result = await request.get(`/Accounts/${sid}`, { auth: authAdmin, @@ -104,7 +109,6 @@ test('account tests', async(t) => { auth: authAdmin, json: true, }); - //console.log(`retrieved account after update: ${JSON.stringify(result)}`); t.ok(Object.keys(result.registration_hook).length === 4, 'successfully removed a hook from account'); /* assign phone number to account */ diff --git a/test/applications.js b/test/applications.js index 5dc44a2..5ede901 100644 --- a/test/applications.js +++ b/test/applications.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ diff --git a/test/auth.js b/test/auth.js index d5967cb..07afdbc 100644 --- a/test/auth.js +++ b/test/auth.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape').test ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ diff --git a/test/create-test-db.js b/test/create-test-db.js index 411a02d..071fff7 100644 --- a/test/create-test-db.js +++ b/test/create-test-db.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const exec = require('child_process').exec ; test('creating jambones_test database', (t) => { diff --git a/test/docker_start.js b/test/docker_start.js index 0fda0bf..0c0a109 100644 --- a/test/docker_start.js +++ b/test/docker_start.js @@ -1,5 +1,4 @@ -const test = require('blue-tape'); -//const test = require('tape').test ; +const test = require('tape'); const exec = require('child_process').exec ; test('starting docker network..', (t) => { diff --git a/test/docker_stop.js b/test/docker_stop.js index 5436e7d..11db6ec 100644 --- a/test/docker_stop.js +++ b/test/docker_stop.js @@ -1,4 +1,4 @@ -const test = require('blue-tape'); +const test = require('tape'); const exec = require('child_process').exec ; test('stopping docker network..', (t) => { diff --git a/test/ms-teams.js b/test/ms-teams.js index 39f0c2d..3be6a46 100644 --- a/test/ms-teams.js +++ b/test/ms-teams.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ diff --git a/test/phone-numbers.js b/test/phone-numbers.js index b6e4da2..a099370 100644 --- a/test/phone-numbers.js +++ b/test/phone-numbers.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ diff --git a/test/remove-test-db.js b/test/remove-test-db.js index 2642e0b..a6e4aed 100644 --- a/test/remove-test-db.js +++ b/test/remove-test-db.js @@ -1,4 +1,4 @@ -const test = require('tape').test ; +const test = require('tape') ; const exec = require('child_process').exec ; const pwd = process.env.CI ? '' : '-p$MYSQL_ROOT_PASSWORD'; diff --git a/test/sbcs.js b/test/sbcs.js index cd74681..64d2cce 100644 --- a/test/sbcs.js +++ b/test/sbcs.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ diff --git a/test/service-providers.js b/test/service-providers.js index 5cd4654..5f122fd 100644 --- a/test/service-providers.js +++ b/test/service-providers.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ diff --git a/test/sip-gateways.js b/test/sip-gateways.js index 3784d91..892d8f4 100644 --- a/test/sip-gateways.js +++ b/test/sip-gateways.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({ diff --git a/test/voip-carriers.js b/test/voip-carriers.js index 8a99168..35af9a8 100644 --- a/test/voip-carriers.js +++ b/test/voip-carriers.js @@ -1,4 +1,4 @@ -const test = require('blue-tape').test ; +const test = require('tape') ; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const authAdmin = {bearer: ADMIN_TOKEN}; const request = require('request-promise-native').defaults({