merge of features from hosted branch (#7)

major merge of features from the hosted branch that was created temporarily during the initial launch of jambonz.org
This commit is contained in:
Dave Horton
2021-06-17 15:56:21 -04:00
committed by GitHub
parent ab7c69c0e8
commit ed51d8b13f
105 changed files with 10330 additions and 1601 deletions
+69 -14
View File
@@ -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({
@@ -16,6 +16,7 @@ process.on('unhandledRejection', (reason, p) => {
test('account tests', async(t) => {
const app = require('../app');
const logger = app.locals.logger;
let sid;
try {
let result;
@@ -25,6 +26,61 @@ test('account tests', async(t) => {
const service_provider_sid = await createServiceProvider(request);
const phone_number_sid = await createPhoneNumber(request, voip_carrier_sid);
/* add invite codes */
result = await request.post('/BetaInviteCodes', {
resolveWithFullResponse: true,
json: true,
auth: authAdmin,
body: {
count: 2
}
});
t.ok(result.statusCode === 200 && 2 === parseInt(result.body.added), 'successfully added 2 beta codes');
//console.log(result.body.codes);
/* claim an invite code */
/*
const mycodes = result.body.codes;
result = await request.post('/InviteCodes', {
resolveWithFullResponse: true,
json: true,
auth: authAdmin,
body: {
test: true,
code: mycodes[0]
}
});
t.ok(result.statusCode === 204, 'successfully tested a beta codes');
result = await request.post('/InviteCodes', {
resolveWithFullResponse: true,
json: true,
auth: authAdmin,
body: {
code: mycodes[0]
}
});
t.ok(result.statusCode === 204, 'successfully claimed a beta codes');
*/
result = await request.post('/BetaInviteCodes', {
resolveWithFullResponse: true,
json: true,
auth: authAdmin,
body: {
count: 50
}
});
t.ok(result.statusCode === 200 && 50 === parseInt(result.body.added), 'successfully added 50 beta codes');
result = await request.post('/BetaInviteCodes', {
resolveWithFullResponse: true,
json: true,
auth: authAdmin,
body: {
}
});
t.ok(result.statusCode === 200 && 1 === parseInt(result.body.added), 'successfully added 1 beta codes');
/* add an account */
result = await request.post('/Accounts', {
resolveWithFullResponse: true,
@@ -36,12 +92,22 @@ test('account tests', async(t) => {
registration_hook: {
url: 'http://example.com/reg',
method: 'get'
}
},
webhook_secret: 'foobar'
}
});
t.ok(result.statusCode === 201, 'successfully created account');
const sid = result.body.sid;
/* query accounts for service providers */
result = await request.get(`/ServiceProviders/${service_provider_sid}/Accounts`, {
auth: authAdmin,
json: true,
resolveWithFullResponse: true,
});
//console.log(result.body);
t.ok(result.statusCode === 200, 'successfully queried accounts for service provider');
/* add an account level api key */
result = await request.post(`/ApiKeys`, {
auth: authAdmin,
@@ -118,23 +184,12 @@ test('account tests', async(t) => {
});
t.ok(result.statusCode === 204, 'successfully assigned phone number to account');
/* cannot delete account that has phone numbers assigned */
result = await request.delete(`/Accounts/${sid}`, {
auth: authAdmin,
resolveWithFullResponse: true,
simple: false,
json: true
});
t.ok(result.statusCode === 422 && result.body.msg === 'cannot delete account with phone numbers', 'cannot delete account with phone numbers');
/* delete account */
await request.delete(`ApiKeys/${apiKeySid}`, {auth: {bearer: accountLevelToken}});
await request.delete(`/PhoneNumbers/${phone_number_sid}`, {auth: authAdmin});
result = await request.delete(`/Accounts/${sid}`, {
auth: authAdmin,
resolveWithFullResponse: true,
});
t.ok(result.statusCode === 204, 'successfully deleted account after removing phone number');
t.ok(result.statusCode === 204, 'successfully deleted account');
await deleteObjectBySid(request, '/VoipCarriers', voip_carrier_sid);
await deleteObjectBySid(request, '/ServiceProviders', service_provider_sid);
+1 -1
View File
@@ -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({
+7 -29
View File
@@ -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({
@@ -56,6 +56,7 @@ test('authentication tests', async(t) => {
json: true,
body: {
name: 'accountA1',
webhook_secret: 'foobar',
registration_hook: {
url: 'http://example.com'
}
@@ -69,6 +70,7 @@ test('authentication tests', async(t) => {
simple: false,
json: true,
body: {
webhook_secret: 'foobar',
name: 'accountA2'
}
});
@@ -80,6 +82,7 @@ test('authentication tests', async(t) => {
simple: false,
json: true,
body: {
webhook_secret: 'foobar',
name: 'accountB1'
}
});
@@ -91,6 +94,7 @@ test('authentication tests', async(t) => {
simple: false,
json: true,
body: {
webhook_secret: 'foobar',
name: 'accountB2'
}
});
@@ -170,6 +174,7 @@ test('authentication tests', async(t) => {
json: true,
body: {
name: 'accountC',
webhook_secret: 'foobar',
service_provider_sid: spA_sid
}
});
@@ -206,7 +211,7 @@ test('authentication tests', async(t) => {
simple: false,
json: true,
body: {
sip_realm: 'sip.foo.bar'
name: 'joe knife'
}
});
//console.log(`result: ${JSON.stringify(result)}`);
@@ -324,33 +329,6 @@ test('authentication tests', async(t) => {
});
t.ok(result.statusCode === 404, 'using account token A1 we are not able to retrieve application A2s');
/* service provider token can not be used to add phone number */
result = await request.post('/PhoneNumbers', {
auth: {bearer: spA_token},
resolveWithFullResponse: true,
simple: false,
json: true,
body: {
number: '16173333456',
voip_carrier_sid
}
});
t.ok(result.statusCode === 403, 'service provider token can not be used to add phone number');
/* account token can not be used to add phone number */
result = await request.post('/PhoneNumbers', {
auth: {bearer: accA1_token},
resolveWithFullResponse: true,
simple: false,
json: true,
body: {
number: '16173333456',
voip_carrier_sid
}
});
t.ok(result.statusCode === 403, 'account level token can not be used to add phone number');
/* account level token can not create token for another account */
result = await request.post('/ApiKeys', {
resolveWithFullResponse: true,
+11 -3
View File
@@ -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) => {
@@ -10,7 +10,7 @@ test('creating jambones_test database', (t) => {
});
test('creating schema', (t) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => {
if (err) return t.end(err);
t.pass('schema successfully created');
t.end();
@@ -18,9 +18,17 @@ test('creating schema', (t) => {
});
test('creating auth token', (t) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/create-admin-token.sql`, (err, stdout, stderr) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/create-admin-token.sql`, (err, stdout, stderr) => {
if (err) return t.end(err);
t.pass('auth token successfully created');
t.end();
});
});
test('add predefined carriers', (t) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/add-predefined-carriers.sql`, (err, stdout, stderr) => {
if (err) return t.end(err);
t.pass('predefined carriers added');
t.end();
});
});
+908
View File
@@ -0,0 +1,908 @@
{
"id": "sub_J5d3C56ZGMDZFA",
"object": "subscription",
"application_fee_percent": null,
"billing_cycle_anchor": 1615381795,
"billing_thresholds": null,
"cancel_at": null,
"cancel_at_period_end": false,
"canceled_at": null,
"collection_method": "charge_automatically",
"created": 1615381795,
"current_period_end": 1618060195,
"current_period_start": 1615381795,
"customer": "cus_J5coVe5AQ5UR6h",
"days_until_due": null,
"default_payment_method": null,
"default_source": null,
"default_tax_rates": [],
"discount": null,
"ended_at": null,
"items": {
"object": "list",
"data": [{
"id": "si_J5d3M9tUQgrnPa",
"object": "subscription_item",
"billing_thresholds": null,
"created": 1615381796,
"metadata": {
"product_sid": "c4403cdb-8e75-4b27-9726-7d8315e3216d"
},
"plan": {
"id": "price_1ISRinAxTxXxh2fmnZmorCm2",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": null,
"amount_decimal": null,
"billing_scheme": "tiered",
"created": 1615143177,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"product": "prod_J4au1au9F2Ysa0",
"tiers": [{
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 1000,
"unit_amount_decimal": "1000",
"up_to": 99
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 900,
"unit_amount_decimal": "900",
"up_to": 250
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 800,
"unit_amount_decimal": "800",
"up_to": 499
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 700,
"unit_amount_decimal": "700",
"up_to": 999
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 500,
"unit_amount_decimal": "500",
"up_to": null
}],
"tiers_mode": "volume",
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "price_1ISRinAxTxXxh2fmnZmorCm2",
"object": "price",
"active": true,
"billing_scheme": "tiered",
"created": 1615143177,
"currency": "usd",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_J4au1au9F2Ysa0",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers_mode": "volume",
"transform_quantity": null,
"type": "recurring",
"unit_amount": null,
"unit_amount_decimal": null
},
"quantity": 100,
"subscription": "sub_J5d3C56ZGMDZFA",
"tax_rates": []
}, {
"id": "si_J5d3F3SkebrH4S",
"object": "subscription_item",
"billing_thresholds": null,
"created": 1615381796,
"metadata": {
"product_sid": "2c815913-5c26-4004-b748-183b459329df"
},
"plan": {
"id": "price_1ISRhKAxTxXxh2fmhsYLgyLM",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": 100,
"amount_decimal": "100",
"billing_scheme": "per_unit",
"created": 1615143086,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"product": "prod_J4at3poNkI5OSA",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "price_1ISRhKAxTxXxh2fmhsYLgyLM",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1615143086,
"currency": "usd",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_J4at3poNkI5OSA",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 100,
"unit_amount_decimal": "100"
},
"quantity": 50,
"subscription": "sub_J5d3C56ZGMDZFA",
"tax_rates": []
}, {
"id": "si_J5d3bcURInlK5Y",
"object": "subscription_item",
"billing_thresholds": null,
"created": 1615381796,
"metadata": {
"product_sid": "35a9fb10-233d-4eb9-aada-78de5814d680"
},
"plan": {
"id": "price_1ISRgHAxTxXxh2fmUg80e3mw",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": null,
"amount_decimal": null,
"billing_scheme": "tiered",
"created": 1615143021,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"product": "prod_J4asDaODFXDjui",
"tiers": [{
"flat_amount": 0,
"flat_amount_decimal": "0",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 10
}, {
"flat_amount": 500,
"flat_amount_decimal": "500",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 30
}, {
"flat_amount": 1000,
"flat_amount_decimal": "1000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 60
}, {
"flat_amount": 2000,
"flat_amount_decimal": "2000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 120
}, {
"flat_amount": 4000,
"flat_amount_decimal": "4000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 300
}, {
"flat_amount": 5000,
"flat_amount_decimal": "5000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": null
}],
"tiers_mode": "volume",
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "price_1ISRgHAxTxXxh2fmUg80e3mw",
"object": "price",
"active": true,
"billing_scheme": "tiered",
"created": 1615143021,
"currency": "usd",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_J4asDaODFXDjui",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers_mode": "volume",
"transform_quantity": null,
"type": "recurring",
"unit_amount": null,
"unit_amount_decimal": null
},
"quantity": 60,
"subscription": "sub_J5d3C56ZGMDZFA",
"tax_rates": []
}],
"has_more": false,
"total_count": 3,
"url": "/v1/subscription_items?subscription=sub_J5d3C56ZGMDZFA"
},
"latest_invoice": {
"id": "in_1ITRnUAxTxXxh2fmmch7bUlr",
"object": "invoice",
"account_country": "US",
"account_name": "drachtio.org",
"account_tax_ids": null,
"amount_due": 96000,
"amount_paid": 96000,
"amount_remaining": 0,
"application_fee_amount": null,
"attempt_count": 1,
"attempted": true,
"auto_advance": false,
"billing_reason": "subscription_create",
"charge": "ch_1ITRnUAxTxXxh2fmvtLpMbNr",
"collection_method": "charge_automatically",
"created": 1615381796,
"currency": "usd",
"custom_fields": null,
"customer": "cus_J5coVe5AQ5UR6h",
"customer_address": null,
"customer_email": "daveh@drachtio.org",
"customer_name": "Dave Horton",
"customer_phone": null,
"customer_shipping": null,
"customer_tax_exempt": "none",
"customer_tax_ids": [],
"default_payment_method": null,
"default_source": null,
"default_tax_rates": [],
"description": null,
"discount": null,
"discounts": [],
"due_date": null,
"ending_balance": 0,
"footer": null,
"hosted_invoice_url": "https://invoice.stripe.com/i/acct_1GjPVFAxTxXxh2fm/invst_J5d3z2L367YU08uV3ZStblw4QzWzN4b",
"invoice_pdf": "https://pay.stripe.com/invoice/acct_1GjPVFAxTxXxh2fm/invst_J5d3z2L367YU08uV3ZStblw4QzWzN4b/pdf",
"last_finalization_error": null,
"lines": {
"object": "list",
"data": [{
"id": "il_1ITRnUAxTxXxh2fmApdPmIJQ",
"object": "line_item",
"amount": 90000,
"currency": "usd",
"description": "100 session × concurrent call session (Tier 2 at $9.00 / month)",
"discount_amounts": [],
"discountable": true,
"discounts": [],
"livemode": false,
"metadata": {},
"period": {
"end": 1618060195,
"start": 1615381795
},
"plan": {
"id": "price_1ISRinAxTxXxh2fmnZmorCm2",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": null,
"amount_decimal": null,
"billing_scheme": "tiered",
"created": 1615143177,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"product": "prod_J4au1au9F2Ysa0",
"tiers": [{
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 1000,
"unit_amount_decimal": "1000",
"up_to": 99
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 900,
"unit_amount_decimal": "900",
"up_to": 250
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 800,
"unit_amount_decimal": "800",
"up_to": 499
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 700,
"unit_amount_decimal": "700",
"up_to": 999
}, {
"flat_amount": null,
"flat_amount_decimal": null,
"unit_amount": 500,
"unit_amount_decimal": "500",
"up_to": null
}],
"tiers_mode": "volume",
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "price_1ISRinAxTxXxh2fmnZmorCm2",
"object": "price",
"active": true,
"billing_scheme": "tiered",
"created": 1615143177,
"currency": "usd",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_J4au1au9F2Ysa0",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers_mode": "volume",
"transform_quantity": null,
"type": "recurring",
"unit_amount": null,
"unit_amount_decimal": null
},
"proration": false,
"quantity": 100,
"subscription": "sub_J5d3C56ZGMDZFA",
"subscription_item": "si_J5d3M9tUQgrnPa",
"tax_amounts": [],
"tax_rates": [],
"type": "subscription"
}, {
"id": "il_1ITRnUAxTxXxh2fmGn4D2s9W",
"object": "line_item",
"amount": 5000,
"currency": "usd",
"description": "50 sip device × registered device (at $1.00 / month)",
"discount_amounts": [],
"discountable": true,
"discounts": [],
"livemode": false,
"metadata": {},
"period": {
"end": 1618060195,
"start": 1615381795
},
"plan": {
"id": "price_1ISRhKAxTxXxh2fmhsYLgyLM",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": 100,
"amount_decimal": "100",
"billing_scheme": "per_unit",
"created": 1615143086,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"product": "prod_J4at3poNkI5OSA",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "price_1ISRhKAxTxXxh2fmhsYLgyLM",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1615143086,
"currency": "usd",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_J4at3poNkI5OSA",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 100,
"unit_amount_decimal": "100"
},
"proration": false,
"quantity": 50,
"subscription": "sub_J5d3C56ZGMDZFA",
"subscription_item": "si_J5d3F3SkebrH4S",
"tax_amounts": [],
"tax_rates": [],
"type": "subscription"
}, {
"id": "il_1ITRnUAxTxXxh2fmmUTvs8b0",
"object": "line_item",
"amount": 0,
"currency": "usd",
"description": "60 per min × api rate limit (Tier 3 at $0.00 / month)",
"discount_amounts": [],
"discountable": true,
"discounts": [],
"livemode": false,
"metadata": {},
"period": {
"end": 1618060195,
"start": 1615381795
},
"plan": {
"id": "price_1ISRgHAxTxXxh2fmUg80e3mw",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": null,
"amount_decimal": null,
"billing_scheme": "tiered",
"created": 1615143021,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"product": "prod_J4asDaODFXDjui",
"tiers": [{
"flat_amount": 0,
"flat_amount_decimal": "0",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 10
}, {
"flat_amount": 500,
"flat_amount_decimal": "500",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 30
}, {
"flat_amount": 1000,
"flat_amount_decimal": "1000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 60
}, {
"flat_amount": 2000,
"flat_amount_decimal": "2000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 120
}, {
"flat_amount": 4000,
"flat_amount_decimal": "4000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 300
}, {
"flat_amount": 5000,
"flat_amount_decimal": "5000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": null
}],
"tiers_mode": "volume",
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "price_1ISRgHAxTxXxh2fmUg80e3mw",
"object": "price",
"active": true,
"billing_scheme": "tiered",
"created": 1615143021,
"currency": "usd",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_J4asDaODFXDjui",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers_mode": "volume",
"transform_quantity": null,
"type": "recurring",
"unit_amount": null,
"unit_amount_decimal": null
},
"proration": false,
"quantity": 60,
"subscription": "sub_J5d3C56ZGMDZFA",
"subscription_item": "si_J5d3bcURInlK5Y",
"tax_amounts": [],
"tax_rates": [],
"type": "subscription"
}, {
"id": "il_1ITRnVAxTxXxh2fm6VDudRAm",
"object": "line_item",
"amount": 1000,
"currency": "usd",
"description": "api rate limit (Tier 3 at $10.00 / month)",
"discount_amounts": [],
"discountable": true,
"discounts": [],
"livemode": false,
"metadata": {},
"period": {
"end": 1618060195,
"start": 1615381795
},
"plan": {
"id": "price_1ISRgHAxTxXxh2fmUg80e3mw",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": null,
"amount_decimal": null,
"billing_scheme": "tiered",
"created": 1615143021,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"product": "prod_J4asDaODFXDjui",
"tiers": [{
"flat_amount": 0,
"flat_amount_decimal": "0",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 10
}, {
"flat_amount": 500,
"flat_amount_decimal": "500",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 30
}, {
"flat_amount": 1000,
"flat_amount_decimal": "1000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 60
}, {
"flat_amount": 2000,
"flat_amount_decimal": "2000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 120
}, {
"flat_amount": 4000,
"flat_amount_decimal": "4000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": 300
}, {
"flat_amount": 5000,
"flat_amount_decimal": "5000",
"unit_amount": null,
"unit_amount_decimal": null,
"up_to": null
}],
"tiers_mode": "volume",
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "price_1ISRgHAxTxXxh2fmUg80e3mw",
"object": "price",
"active": true,
"billing_scheme": "tiered",
"created": 1615143021,
"currency": "usd",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_J4asDaODFXDjui",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers_mode": "volume",
"transform_quantity": null,
"type": "recurring",
"unit_amount": null,
"unit_amount_decimal": null
},
"proration": false,
"quantity": 0,
"subscription": "sub_J5d3C56ZGMDZFA",
"subscription_item": "si_J5d3bcURInlK5Y",
"tax_amounts": [],
"tax_rates": [],
"type": "subscription"
}],
"has_more": false,
"total_count": 4,
"url": "/v1/invoices/in_1ITRnUAxTxXxh2fmmch7bUlr/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "0A22219A-0001",
"on_behalf_of": null,
"paid": true,
"payment_intent": {
"id": "pi_1ITRnUAxTxXxh2fmmyjspFCb",
"object": "payment_intent",
"amount": 96000,
"amount_capturable": 0,
"amount_received": 96000,
"application": null,
"application_fee_amount": null,
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"charges": {
"object": "list",
"data": [{
"id": "ch_1ITRnUAxTxXxh2fmvtLpMbNr",
"object": "charge",
"amount": 96000,
"amount_captured": 96000,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_1ITRnVAxTxXxh2fmTGIuTAaB",
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"calculated_statement_descriptor": "DRACHTIO COMM SVCS LLC",
"captured": true,
"created": 1615381796,
"currency": "usd",
"customer": "cus_J5coVe5AQ5UR6h",
"description": "Subscription creation",
"destination": null,
"dispute": null,
"disputed": false,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"invoice": "in_1ITRnUAxTxXxh2fmmch7bUlr",
"livemode": false,
"metadata": {},
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 16,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": "pi_1ITRnUAxTxXxh2fmmyjspFCb",
"payment_method": "card_1ITRZIAxTxXxh2fmgZWoCsPx",
"payment_method_details": {
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": null
},
"country": "US",
"exp_month": 9,
"exp_year": 2024,
"fingerprint": "KDQxr00TBv7zH8Sg",
"funding": "credit",
"installments": null,
"last4": "4242",
"network": "visa",
"three_d_secure": null,
"wallet": null
},
"type": "card"
},
"receipt_email": null,
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_1GjPVFAxTxXxh2fm/ch_1ITRnUAxTxXxh2fmvtLpMbNr/rcpt_J5d3fiWQsaYt9Pmkw0SEV34LbxYJyGl",
"refunded": false,
"refunds": {
"object": "list",
"data": [],
"has_more": false,
"total_count": 0,
"url": "/v1/charges/ch_1ITRnUAxTxXxh2fmvtLpMbNr/refunds"
},
"review": null,
"shipping": null,
"source": {
"id": "card_1ITRZIAxTxXxh2fmgZWoCsPx",
"object": "card",
"address_city": null,
"address_country": null,
"address_line1": null,
"address_line1_check": null,
"address_line2": null,
"address_state": null,
"address_zip": null,
"address_zip_check": null,
"brand": "Visa",
"country": "US",
"customer": "cus_J5coVe5AQ5UR6h",
"cvc_check": null,
"dynamic_last4": null,
"exp_month": 9,
"exp_year": 2024,
"fingerprint": "KDQxr00TBv7zH8Sg",
"funding": "credit",
"last4": "4242",
"metadata": {},
"name": null,
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Drachtio Comm Svcs LLC",
"statement_descriptor_suffix": null,
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}],
"has_more": false,
"total_count": 1,
"url": "/v1/charges?payment_intent=pi_1ITRnUAxTxXxh2fmmyjspFCb"
},
"client_secret": "pi_1ITRnUAxTxXxh2fmmyjspFCb_secret_6FB5iXrTQ3w1f7ckUWeycmYoc",
"confirmation_method": "automatic",
"created": 1615381796,
"currency": "usd",
"customer": "cus_J5coVe5AQ5UR6h",
"description": "Subscription creation",
"invoice": "in_1ITRnUAxTxXxh2fmmch7bUlr",
"last_payment_error": null,
"livemode": false,
"metadata": {},
"next_action": null,
"on_behalf_of": null,
"payment_method": null,
"payment_method_options": {
"card": {
"installments": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": ["card"],
"receipt_email": null,
"review": null,
"setup_future_usage": "off_session",
"shipping": null,
"source": "card_1ITRZIAxTxXxh2fmgZWoCsPx",
"statement_descriptor": "Drachtio Comm Svcs LLC",
"statement_descriptor_suffix": null,
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
},
"payment_settings": {
"payment_method_options": null,
"payment_method_types": null
},
"period_end": 1615381795,
"period_start": 1615381795,
"post_payment_credit_notes_amount": 0,
"pre_payment_credit_notes_amount": 0,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": null,
"status": "paid",
"status_transitions": {
"finalized_at": 1615381795,
"marked_uncollectible_at": null,
"paid_at": 1615381795,
"voided_at": null
},
"subscription": "sub_J5d3C56ZGMDZFA",
"subtotal": 96000,
"tax": null,
"tax_percent": null,
"total": 96000,
"total_discount_amounts": [],
"total_tax_amounts": [],
"transfer_data": null,
"webhooks_delivered_at": null
},
"livemode": false,
"metadata": {},
"next_pending_invoice_item_invoice": null,
"pause_collection": null,
"pending_invoice_item_interval": null,
"pending_setup_intent": null,
"pending_update": null,
"plan": null,
"quantity": null,
"schedule": null,
"start_date": 1615381795,
"status": "active",
"tax_percent": null,
"transfer_data": null,
"trial_end": null,
"trial_start": null
}
+12
View File
@@ -0,0 +1,12 @@
{
"type": "service_account",
"project_id": "foobar",
"private_key_id": "17a374747574b98284367f1fd2197401c8",
"private_key": "-----BEGIN PRIVATE KEY-----\nkdkdkdkdkdkdkdkdkdkdkdkdkddjdjdjdjjEVtS\n8cZeK4w128sbogusVmVARsj5/\nw6Ou08xBX+e1rsKkiaGnzuKhuZczwWMuAwfnBtNQhw2ZUJCDkQfk7tT1100CAi4h\nLAWX/sufHNi9h2z7yCAeRDGqmIM89lRguycKexy8MM4NZRxAIrLs7LIGhTczMFUC\n6TxaFWlXAgMBAAECggEAMHFgrcUn0ATiQcxkeplWom9Ki7gTuhO1wQeOqRtTIZ+d\nCQOigARklx0YTQlsqoG/acLSfeAcfyLWEklULaqJbeghl9KPE4FwPX13VPlZHCMj\nyXUycrjlxw4tHpcy9egDjj5c4XSiUQ/3nNrn0q0EMxFleM3Mhhj1408HifBLH3KY\nKCA+fq+tqmS/daCUgs7jEZCo4z8qFmz0npHUcQ5P7SrsYf00Di9RH8m1Tc9aXU6H\nkMSCfM8/UpPvt+lOQktWjDKP2APowuPyfl4RgX+9jNUm8h2y9jYKeyTelQC0CAUM\nW4ZB6tiDbXOVeP9miXgVwv3WUh4Mrwufar5e0DeqvQKBgQDKZ6Vk7CEVfGQgBoUU\neWo203Tmc2W5qnXRh0pa1VwUtgte+D7l8Lwfc0gCfjbkk7EXKQrQ19jtTwZAzvHz\nsgziQ8H1IDLQBBtknWxuOJbNuronZE6NMWNp+ULu2Y4XN6MnD75sPgtxFMPUUuWI\n5CdXPKweyC+BKC99ukIposGWcwKBgQDGVCYik8nh3fX+BkC1xrFGZ4z3jIqZs8bk\nLFDCiDGwAJTXee2/L5wUJIv4UGoO822OOg+8ftMCtDmdrIkOjsXUPrhbnrGyqZgM\nEC4T3CNDiQXHqxw4tjg4eM5Vcwi6KkuhSAcClz/aaZ1T5jk0QGdF7UpqKcbsURx8\n5hGcscVEjQKBgBXPcV0crLv5+XgR+8knBDEAPDqQ+Mc2/Rck8vgywYdhznvfWDfC\n5yKkc4ABRbz/xTdvrsCuYavAtjXJlvzhlM3U61OUsqUDrEf9Rq/h3S4yDtkrz+Mb\nDVFgELxYKR2LW0NcSPK1BNqcmDWK8Tz9CNg3q3xtqeDLCcMMjRCbfyzNAoGAWlLC\nl2bFP6eNu6XvXJnj7JOGYMtR6BQ3FX2VPjM2pdht8QBnpXWyWH4YfPtqgeqdT3Pj\n7M25nfakcsm8FbQyJqp13cwVU6/nPj80LPlJ2h0SU8/6510dl6J1Hfdo1xgiH46l\nGqn1e6wz6ZzlGoXmQrOB+32RSdja54sEJF/V3pUCgYAoGFZAGVBuWqipbBLdQqNl\n1ppdEliEBhDPq4cZAnNx1lvnmFn8D5bqi+rB8bkqvGcR921AMLDadasHX4BJAJw+\nQoSx1wqy9Zsiaz9EzWUxHtnKFOzMVeVz/RJqH8hNu4xb6Lv50BgTztoO+bGIOAJ/\nVaY6N4gOkiAihhQzsSnLvQ==\n-----END PRIVATE KEY-----\n",
"client_email": "cloud-speech-testing@foobar.iam.gserviceaccount.com",
"client_id": "109945388890626427918",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/cloud-speech-testing%40foobarg.iam.gserviceaccount.com"
}
+2 -3
View File
@@ -1,12 +1,11 @@
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) => {
t.plan(1);
exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => {
setTimeout(() => {
t.pass('docker started');
t.end(err);
}, 15000);
});
});
+1 -1
View File
@@ -1,4 +1,4 @@
const test = require('blue-tape');
const test = require('tape');
const exec = require('child_process').exec ;
test('stopping docker network..', (t) => {
+4
View File
@@ -1,6 +1,7 @@
require('./docker_start');
require('./create-test-db');
require('./sip-gateways');
require('./smpp-gateways');
require('./service-providers');
require('./voip-carriers');
require('./accounts');
@@ -9,4 +10,7 @@ require('./applications');
require('./auth');
require('./sbcs');
require('./ms-teams');
require('./speech-credentials');
require('./recent-calls');
require('./webapp_tests');
require('./docker_stop');
+1 -1
View File
@@ -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({
+19
View File
@@ -0,0 +1,19 @@
const bent = require('bent');
const getJSON = bent('GET', 200);
const request = require('request');
require('request-debug')(request);
const test = async() => {
request.get('https://api.github.com/user', {
headers: {
Authorization: `Bearer ${process.env.GH_CODE}`,
Accept: 'application/json',
'User-Agent': 'jambonz.us'
}
}, (err, response, body) => {
if (err) console.log(error);
else console.log(body);
})
};
test();
+14
View File
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test oauth signup</title>
</head>
<body>
<a href="https://github.com/login/oauth/authorize?client_id=a075a5889264b8fbc831&state=foobar&allow_signup=false">Github</a>
</body>
</html>
+11 -48
View File
@@ -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({
@@ -19,19 +19,6 @@ test('phone number tests', async(t) => {
/* add service provider, phone number, and voip carrier */
const voip_carrier_sid = await createVoipCarrier(request);
/* provision phone number - failure case: voip_carrier_sid is required */
result = await request.post('/PhoneNumbers', {
resolveWithFullResponse: true,
simple: false,
auth: authAdmin,
json: true,
body: {
number: '15083084809'
}
});
t.ok(result.statusCode === 400 && result.body.msg === 'voip_carrier_sid is required',
'voip_carrier_sid is required when provisioning a phone number');
/* provision phone number - failure case: digits only */
result = await request.post('/PhoneNumbers', {
resolveWithFullResponse: true,
@@ -43,37 +30,9 @@ test('phone number tests', async(t) => {
voip_carrier_sid
}
});
t.ok(result.statusCode === 400 && result.body.msg === 'phone number must only include digits',
'service_provider_sid is required when provisioning a phone number');
/* provision phone number - failure case: insufficient digits */
result = await request.post('/PhoneNumbers', {
resolveWithFullResponse: true,
simple: false,
auth: authAdmin,
json: true,
body: {
number: '1508308',
voip_carrier_sid
}
});
//console.log(`result: ${JSON.stringify(result)}`);
t.ok(result.statusCode === 400 && result.body.msg === 'invalid phone number: insufficient digits',
'invalid phone number: insufficient digits');
/* provision phone number - failure case: invalid US number */
result = await request.post('/PhoneNumbers', {
resolveWithFullResponse: true,
simple: false,
auth: authAdmin,
json: true,
body: {
number: '150830848091',
voip_carrier_sid
}
});
t.ok(result.statusCode === 400 && result.body.msg === 'invalid US phone number',
'invalid US phone number');
t.ok(result.statusCode === 201,
'accepts E.164 format');
const sid = result.body.sid;
/* add a phone number */
result = await request.post('/PhoneNumbers', {
@@ -86,17 +45,17 @@ test('phone number tests', async(t) => {
}
});
t.ok(result.statusCode === 201, 'successfully created phone number');
const sid = result.body.sid;
const sid2 = result.body.sid;
/* query all phone numbers */
result = await request.get('/PhoneNumbers', {
auth: authAdmin,
json: true,
});
t.ok(result.length === 1 , 'successfully queried all phone numbers');
t.ok(result.length === 2, 'successfully queried all phone numbers');
/* query one phone numbers */
result = await request.get(`/PhoneNumbers/${sid}`, {
result = await request.get(`/PhoneNumbers/${sid2}`, {
auth: authAdmin,
json: true,
});
@@ -108,6 +67,10 @@ test('phone number tests', async(t) => {
resolveWithFullResponse: true,
});
t.ok(result.statusCode === 204, 'successfully deleted phone number');
result = await request.delete(`/PhoneNumbers/${sid2}`, {
auth: authAdmin,
resolveWithFullResponse: true,
});
await deleteObjectBySid(request, '/VoipCarriers', voip_carrier_sid);
+79
View File
@@ -0,0 +1,79 @@
const test = require('tape') ;
const fs = require('fs');
const jwt = require('jsonwebtoken');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({
baseUrl: 'http://127.0.0.1:3000/v1'
});
const consoleLogger = {debug: console.log, info: console.log, error: console.error}
const {writeCdrs} = require('@jambonz/time-series')(consoleLogger, '127.0.0.1');
const {createServiceProvider, createAccount, deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
test('recent calls tests', async(t) => {
const app = require('../app');
const jsonKey = fs.readFileSync(`${__dirname}/data/test.json`, {encoding: 'utf8'});
let sid;
try {
let result;
const service_provider_sid = await createServiceProvider(request);
const account_sid = await createAccount(request, service_provider_sid);
const token = jwt.sign({
account_sid
}, process.env.JWT_SECRET, { expiresIn: '1h' });
const authUser = {bearer: token};
/* write sample cdr data */
const points = 500;
const data = [];
const start = new Date(Date.now() - (30 * 24 * 60 * 60 * 1000));
const now = new Date();
const increment = (now.getTime() - start.getTime()) / points;
for (let i =0 ; i < 500; i++) {
const attempted_at = new Date(start.getTime() + (i * increment));
const failed = 0 === i % 5;
data.push({
call_sid: 'b6f48929-8e86-4d62-ae3b-64fb574d91f6',
from: '15083084809',
to: '18882349999',
answered: !failed,
sip_callid: '685cd008-0a66-4974-b37a-bdd6d9a3c4aa@192.168.1.100',
sip_status: 200,
duration: failed ? 0 : 45,
attempted_at: attempted_at.getTime(),
answered_at: attempted_at.getTime() + 3000,
terminated_at: attempted_at.getTime() + 45000,
termination_reason: 'caller hungup',
host: "192.168.1.100",
remote_host: '3.55.24.34',
account_sid: account_sid,
direction: 0 === i % 2 ? 'inbound' : 'outbound',
trunk: 0 === i % 2 ? 'twilio' : 'user'
});
}
await writeCdrs(data);
t.pass('seeded cdr data');
/* query last 7 days */
result = await request.get(`/Accounts/${account_sid}/RecentCalls?page=1&count=25`, {
auth: authUser,
json: true,
});
await deleteObjectBySid(request, '/Accounts', account_sid);
await deleteObjectBySid(request, '/ServiceProviders', service_provider_sid);
//t.end();
}
catch (err) {
console.error(err);
t.end(err);
}
});
+4 -23
View File
@@ -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({
@@ -17,18 +17,6 @@ test('sbc_addresses tests', async(t) => {
let result;
const service_provider_sid = await createServiceProvider(request);
/* add a community sbc */
result = await request.post('/Sbcs', {
resolveWithFullResponse: true,
auth: authAdmin,
json: true,
body: {
ipv4: '192.168.1.1'
}
});
t.ok(result.statusCode === 201, 'successfully created community sbc ');
const sid1 = result.body.sid;
/* add a service provider sbc */
result = await request.post('/Sbcs', {
resolveWithFullResponse: true,
@@ -40,24 +28,17 @@ test('sbc_addresses tests', async(t) => {
}
});
t.ok(result.statusCode === 201, 'successfully created service provider sbc ');
const sid2 = result.body.sid;
result = await request.get('/Sbcs', {
resolveWithFullResponse: true,
auth: authAdmin,
json: true
});
t.ok(result.body.length === 1 && result.body[0].ipv4 === '192.168.1.1', 'successfully retrieved community sbc');
const sid = result.body.sid;
result = await request.get(`/Sbcs?service_provider_sid=${service_provider_sid}`, {
resolveWithFullResponse: true,
auth: authAdmin,
json: true
});
//console.log(result.body)
t.ok(result.body.length === 1 && result.body[0].ipv4 === '192.168.1.4', 'successfully retrieved service provider sbc');
await deleteObjectBySid(request, '/Sbcs', sid1);
await deleteObjectBySid(request, '/Sbcs', sid2);
await deleteObjectBySid(request, '/Sbcs', sid);
await deleteObjectBySid(request, '/ServiceProviders', service_provider_sid);
//t.end();
+17 -8
View File
@@ -45,15 +45,23 @@ const createSchema = () => {
const seedDb = () => {
return new Promise((resolve, reject) => {
console.log('seeding database..')
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/create-default-service-provider-and-account.sql`, (err) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/seed-integration-test.sql`, (err) => {
if (err) return reject(err);
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/create-admin-token.sql`, (err) => {
if (err) return reject(err);
exec(`node ${__dirname}/../db/reset_admin_password.js`, (err) => {
if (err) return reject(err);
resolve();
});
});
resolve();
});
});
};
const resetAdminPassword = () => {
return new Promise((resolve, reject) => {
/* not needed when running jambonz hosting mode */
if (process.env.STRIPE_API_KEY) return resolve();
console.log('creating admin user..')
exec(`node ${__dirname}/../db/reset_admin_password.js`, (err, stdout, stderr) => {
console.log(stdout);
console.log(stderr);
if (err) return reject(err);
resolve();
});
});
};
@@ -72,6 +80,7 @@ startDocker()
.then(createDb)
.then(createSchema)
.then(seedDb)
.then(resetAdminPassword)
.then(() => {
console.log('ready for testing!');
require('..');
+12 -2
View File
@@ -1,9 +1,10 @@
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({
baseUrl: 'http://127.0.0.1:3000/v1'
});
const {deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
@@ -94,7 +95,6 @@ test('service provider tests', async(t) => {
});
t.ok(result.name === 'johndoe' && result.root_domain === 'example.com', 'successfully retrieved service provider by sid');
/* update service providers */
result = await request.put(`/ServiceProviders/${sid}`, {
auth: authAdmin,
@@ -106,6 +106,16 @@ test('service provider tests', async(t) => {
});
t.ok(result.statusCode === 204, 'successfully updated service provider');
/* add a predefined carrier for a service provider */
result = await request.post(`/ServiceProviders/${sid}/PredefinedCarriers/7d509a18-bbff-4c5d-b21e-b99bf8f8c49a`, {
auth: authAdmin,
json: true,
resolveWithFullResponse: true,
});
t.ok(result.statusCode === 201, 'successfully added predefined carrier to service provider');
await deleteObjectBySid(request, '/VoipCarriers', result.body.sid);
/* delete service providers */
result = await request.delete(`/ServiceProviders/${sid}`, {
auth: authAdmin,
+5 -2
View File
@@ -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({
@@ -25,6 +25,7 @@ test('sip gateway tests', async(t) => {
body: {
voip_carrier_sid,
ipv4: '192.168.1.1',
netmask: 32,
inbound: true,
outbound: true
}
@@ -34,6 +35,7 @@ test('sip gateway tests', async(t) => {
/* query all sip gateways */
result = await request.get('/SipGateways', {
qs: {voip_carrier_sid},
auth: authAdmin,
json: true,
});
@@ -55,12 +57,13 @@ test('sip gateway tests', async(t) => {
resolveWithFullResponse: true,
body: {
port: 5061,
netmask:24,
outbound: false
}
});
t.ok(result.statusCode === 204, 'successfully updated voip carrier');
/* delete sip gatewas */
/* delete sip gateways */
result = await request.delete(`/SipGateways/${sid}`, {
resolveWithFullResponse: true,
simple: false,
+88
View File
@@ -0,0 +1,88 @@
const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({
baseUrl: 'http://127.0.0.1:3000/v1'
});
const {createVoipCarrier, deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
test('smpp gateway tests', async(t) => {
const app = require('../app');
let sid;
try {
let result;
const voip_carrier_sid = await createVoipCarrier(request);
/* add a smpp gateway */
result = await request.post('/SmppGateways', {
resolveWithFullResponse: true,
auth: authAdmin,
json: true,
body: {
voip_carrier_sid,
ipv4: '192.168.1.1',
netmask: 32,
inbound: true,
outbound: true,
use_tls: true,
is_primary: true
}
});
t.ok(result.statusCode === 201, 'successfully created smpp gateway ');
const sid = result.body.sid;
/* query all smpp gateways */
console.log('querying with ')
result = await request.get('/SmppGateways', {
qs: {voip_carrier_sid},
auth: authAdmin,
json: true,
});
t.ok(result.length === 1 , 'successfully queried all smpp gateways');
/* query one smpp gateway */
result = await request.get(`/SmppGateways/${sid}`, {
auth: authAdmin,
json: true,
});
//console.log(`result: ${JSON.stringify(result)}`);
t.ok(result.ipv4 === '192.168.1.1' , 'successfully retrieved voip carrier by sid');
/* update smpp gateway */
result = await request.put(`/SmppGateways/${sid}`, {
auth: authAdmin,
json: true,
resolveWithFullResponse: true,
body: {
port: 5061,
netmask:24,
outbound: false
}
});
t.ok(result.statusCode === 204, 'successfully updated voip carrier');
/* delete smpp gatewas */
result = await request.delete(`/SmppGateways/${sid}`, {
resolveWithFullResponse: true,
simple: false,
json: true,
auth: authAdmin
});
//console.log(`result: ${JSON.stringify(result)}`);
t.ok(result.statusCode === 204, 'successfully deleted smpp gateway');
await deleteObjectBySid(request, '/VoipCarriers', voip_carrier_sid);
//t.end();
}
catch (err) {
console.error(err);
t.end(err);
}
});
+123
View File
@@ -0,0 +1,123 @@
const test = require('tape') ;
const fs = require('fs');
const jwt = require('jsonwebtoken');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({
baseUrl: 'http://127.0.0.1:3000/v1'
});
const {createServiceProvider, createAccount, deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
test('speech credentials tests', async(t) => {
const app = require('../app');
const jsonKey = fs.readFileSync(`${__dirname}/data/test.json`, {encoding: 'utf8'});
let sid;
try {
let result;
const service_provider_sid = await createServiceProvider(request);
const account_sid = await createAccount(request, service_provider_sid);
/* add a speech credential to a service provider */
result = await request.post(`/ServiceProviders/${service_provider_sid}/SpeechCredentials`, {
resolveWithFullResponse: true,
simple: false,
auth: authAdmin,
json: true,
body: {
vendor: 'google',
service_key: jsonKey
}
});
t.ok(result.statusCode === 201, 'successfully added a speech credential to service provider');
//console.log(result.body)
const speech_credential_sid = result.body.sid;
/* query speech credentials for a service provider */
result = await request.get(`/ServiceProviders/${service_provider_sid}/SpeechCredentials`, {
resolveWithFullResponse: true,
simple: false,
auth: authAdmin,
json: true,
});
//console.log(result.body)
t.ok(result.statusCode === 200, 'successfully queried speech credential to service provider');
await deleteObjectBySid(request, `/ServiceProviders/${service_provider_sid}/SpeechCredentials`, speech_credential_sid);
const token = jwt.sign({
account_sid
}, process.env.JWT_SECRET, { expiresIn: '1h' });
const authUser = {bearer: token};
/* add a credential */
result = await request.post(`/Accounts/${account_sid}/SpeechCredentials`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
vendor: 'google',
service_key: jsonKey
}
});
t.ok(result.statusCode === 201, 'successfully added speech credential');
const sid1 = result.body.sid;
/* return 403 if invalid account is used */
result = await request.post(`/Accounts/foobarbaz/SpeechCredentials`, {
resolveWithFullResponse: true,
simple: false,
auth: authUser,
json: true,
body: {
vendor: 'google',
service_key: jsonKey
}
});
t.ok(result.statusCode === 403, 'returns 403 Forbidden if Account does not match jwt');
/* query one credential */
result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/${sid1}`, {
auth: authAdmin,
json: true,
});
t.ok(result.vendor === 'google' , 'successfully retrieved speech credential by sid');
/* query all credentials */
result = await request.get(`/Accounts/${account_sid}/SpeechCredentials`, {
auth: authAdmin,
json: true,
});
t.ok(result[0].vendor === 'google' && result.length === 1, 'successfully retrieved all speech credentials');
/* return 404 when deleting unknown credentials */
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/foobarbaz`, {
auth: authUser,
resolveWithFullResponse: true,
simple: false
});
t.ok(result.statusCode === 404, 'return 404 when attempting to delete unknown credential');
/* delete the credential */
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${sid1}`, {
auth: authUser,
resolveWithFullResponse: true,
});
t.ok(result.statusCode === 204, 'successfully deleted speech credential');
await deleteObjectBySid(request, '/Accounts', account_sid);
await deleteObjectBySid(request, '/ServiceProviders', service_provider_sid);
//t.end();
}
catch (err) {
console.error(err);
t.end(err);
}
});
+17 -1
View File
@@ -1,3 +1,5 @@
const bytesToUuid = require("uuid/lib/bytesToUuid");
const uuid = require('uuid').v4;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN};
@@ -42,7 +44,8 @@ async function createAccount(request, service_provider_sid, name = 'daveh') {
json: true,
body: {
name,
service_provider_sid
service_provider_sid,
webhook_secret: 'foobar'
}
});
return result.sid;
@@ -66,6 +69,18 @@ async function createApplication(request, account_sid, name = 'daveh') {
return result.sid;
}
async function createApiKey(request, account_sid) {
const result = await request.post('/ApiKeys', {
auth: authAdmin,
json: true,
body: {
account_sid,
token: uuid()
}
});
return result.sid;
}
async function deleteObjectBySid(request, path, sid) {
const result = await request.delete(`${path}/${sid}`, {
auth: authAdmin,
@@ -79,5 +94,6 @@ module.exports = {
createPhoneNumber,
createAccount,
createApplication,
createApiKey,
deleteObjectBySid
};
+26 -2
View File
@@ -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({
@@ -105,7 +105,7 @@ test('voip carrier tests', async(t) => {
//console.log(`result: ${JSON.stringify(result)}`);
t.ok(result.statusCode === 204, 'successfully deleted voip carrier');
/* create voipd carrier that is a customer PBX */
/* create voip carrier that is a customer PBX */
const service_provider_sid = await createServiceProvider(request);
const account_sid = await createAccount(request, service_provider_sid);
const account_sid2 = await createAccount(request, service_provider_sid, 'another');
@@ -189,6 +189,30 @@ test('voip carrier tests', async(t) => {
sid = result.body.sid;
await deleteObjectBySid(request, '/VoipCarriers', sid);
/* add a voip carrier for a service provider */
result = await request.post(`/ServiceProviders/${service_provider_sid}/VoipCarriers`, {
resolveWithFullResponse: true,
auth: authAdmin,
json: true,
body: {
name: 'twilio',
e164_leading_plus: true
}
});
t.ok(result.statusCode === 201, 'successfully created voip carrier for a service provider');
sid = result.body.sid;
/* list voip carriers for a service provider */
result = await request.get(`/ServiceProviders/${service_provider_sid}/VoipCarriers`, {
resolveWithFullResponse: true,
auth: authAdmin,
json: true,
});
//console.log(result.body);
t.ok(result.statusCode === 200, 'successfully retrieved voip carrier for a service provider');
sid = result.body[0].voip_carrier_sid;
await deleteObjectBySid(request, '/VoipCarriers', sid);
await deleteObjectBySid(request, '/Applications', application_sid);
await deleteObjectBySid(request, '/Accounts', account_sid);
await deleteObjectBySid(request, '/Accounts', account_sid2);
+512
View File
@@ -0,0 +1,512 @@
const test = require('tape') ;
const exec = require('child_process').exec ;
const Account = require('../lib/models/account');
const request = require('request-promise-native').defaults({
baseUrl: 'http://127.0.0.1:3000/v1'
});
const theOneAndOnlyServiceProviderSid = '2708b1b3-2736-40ea-b502-c53d8396247f';
const {createApiKey} = require('./utils');
const sleepFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
test('re-creating schema', (t) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => {
if (err) return t.end(err);
t.pass('schema successfully created');
t.end();
});
});
test('seeding database for webapp tests', (t) => {
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/webapp-tests.sql`, (err, stdout, stderr) => {
if (err) return t.end(err);
t.pass('successfully re-seeded database');
t.end();
});
});
test('webapp tests', async(t) => {
const app = require('../app');
let sid;
try {
let result;
/* create a new user/account using email/password */
const code = '123456';
result = await request.post('/register', {
resolveWithFullResponse: true,
json: true,
body: {
service_provider_sid: theOneAndOnlyServiceProviderSid,
provider: 'local',
name: 'Joe User',
email: 'joe@user.com',
password: 'fiddlesticks',
email_activation_code: code
}
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.pristine === true &&
!result.body.is_active && result.body.root_domain === 'sip.yakeeda.com',
'successfully created a user and account and got jwt using email validation');
const {user_sid, account_sid, jwt} = result.body;
let authUser = {bearer: jwt};
/* invalid code */
result = await request.put('/ActivationCode/38383', {
resolveWithFullResponse: true,
auth: authUser,
simple: false,
json: true,
body: {
user_sid,
type: 'email'
}
});
t.ok(result.statusCode === 400, 'fails to validate email with invalid code');
/* invalid user */
result = await request.put(`/ActivationCode/${code}`, {
resolveWithFullResponse: true,
auth: authUser,
simple: false,
json: true,
body: {
user_sid: 'foobar',
type: 'email'
}
});
t.ok(result.statusCode === 400, 'fails to validate email with invalid user');
/* successfully validate the password */
result = await request.put(`/ActivationCode/${code}`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
user_sid,
type: 'email'
}
});
t.ok(result.statusCode === 204, 'successfully validated email and activated account');
/* create a phone validation code */
result = await request.post('/ActivationCode', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
simple: false,
body: {
user_sid: 'foobar',
type: 'phone',
value: '16173333456',
code: '12389'
}
});
t.ok(result.statusCode === 400, 'returns 400 bad request creating activation code with invalid user_sid');
result = await request.post('/ActivationCode', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
simple: false,
body: {
user_sid,
type: 'foobar',
value: '16173333456',
code: '12389'
}
});
t.ok(result.statusCode === 400, 'returns 400 bad request creating activation code with invalid type');
result = await request.post('/ActivationCode', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
simple: false,
body: {
user_sid,
type: 'email',
value: 'notanemail',
code: '12389'
}
});
t.ok(result.statusCode === 400, 'returns 400 bad request creating activation code with invalid email');
/* create a phone validation code */
result = await request.post('/ActivationCode', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
user_sid,
type: 'phone',
value: '16173333456',
code: '12389'
}
});
t.ok(result.statusCode === 204, 'successfully added a phone validation code');
/* successfully validate the code */
result = await request.put('/ActivationCode/12389', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
user_sid,
type: 'phone'
}
});
t.ok(result.statusCode === 204, 'successfully validated phone number');
/* check availability of a phone numbers and email */
result = await request.get('/Availability?type=phone&value=16173333456', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
t.ok(result.statusCode === 200 && result.body.available === false, 'indicates when phone number is not available');
result = await request.get('/Availability?type=phone&value=15083084809', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
t.ok(result.statusCode === 200 && result.body.available === true, 'indicates when phone number is available');
result = await request.get('/Availability?type=email&value=joe@user.com', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
t.ok(result.statusCode === 200 && result.body.available === false, 'indicates when email is not available');
result = await request.get('/Availability?type=email&value=jim@user.com', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
t.ok(result.statusCode === 200 && result.body.available === true, 'indicates when email is available');
/* check if a subdomain is available */
result = await request.get('/Availability?type=subdomain&value=mycompany.sip.jambonz.us', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
t.ok(result.statusCode === 200 && result.body.available === true, 'indicates when subdomain is available');
/* these hit the DNS provider (dnsmadeeasy) so only do as needed */
if (process.env.DME_API_KEY) {
/* add a subdomain to the account */
result = await request.post(`Accounts/${account_sid}/SipRealms/test.yakeeda.com`, {
resolveWithFullResponse: true,
auth: authUser,
});
t.ok(result.statusCode === 204, 'added subdomain');
/* change the subdomain */
result = await request.post(`Accounts/${account_sid}/SipRealms/myco.yakeeda.com`, {
resolveWithFullResponse: true,
auth: authUser,
});
t.ok(result.statusCode === 204, 'added subdomain');
/* retrieve account and verify sip_realm */
result = await request.get(`Accounts/${account_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.sip_realm === 'myco.yakeeda.com' && result.body.is_active,
'sip_realm successfully added to account');
/* check if a subdomain is available */
result = await request.get('/Availability?type=subdomain&value=myco.yakeeda.com', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
t.ok(result.statusCode === 200 && result.body.available === false, 'indicates when subdomain is not available');
}
/* retrieve test number and app for a service provider */
result = await request.get(`/AccountTest/${theOneAndOnlyServiceProviderSid}`, {
resolveWithFullResponse: true,
json: true,
});
//console.log(JSON.stringify(result.body));
t.ok(result.statusCode === 200 &&
result.body.phonenumbers.length === 1 && result.body.applications.length === 1, 'retrieves test number and application');
/* update user name */
result = await request.put(`/Users/foobar`, {
resolveWithFullResponse: true,
json: true,
simple: false,
auth: authUser,
body: {
name: 'Jane Doe'
}
});
t.ok(result.statusCode === 403, 'rejects attempt to update different user');
/* update user name */
result = await request.put(`/Users/${user_sid}`, {
resolveWithFullResponse: true,
json: true,
auth: authUser,
body: {
name: 'Jane Doe'
}
});
t.ok(result.statusCode === 204, 'updates user name');
/* update password */
result = await request.put(`/Users/${user_sid}`, {
resolveWithFullResponse: true,
json: true,
auth: authUser,
body: {
old_password: 'fiddlesticks',
new_password: 'foobarbazzle'
}
});
t.ok(result.statusCode === 204, 'updates user password');
/* update email */
result = await request.put(`/Users/${user_sid}`, {
resolveWithFullResponse: true,
json: true,
auth: authUser,
body: {
email: 'janedoe@gmail.com',
email_activation_code: '39877'
}
});
t.ok(result.statusCode === 204, 'updates email address');
/* successfully validate the new email */
result = await request.put('/ActivationCode/39877', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
user_sid,
type: 'email'
}
});
t.ok(result.statusCode === 204, 'successfully validated the new email address');
/* add api keys */
await createApiKey(request, account_sid);
await createApiKey(request, account_sid);
/* retrieve my own user info */
result = await request.get(`/Users/me`, {
resolveWithFullResponse: true,
json: true,
auth: authUser,
});
//console.log(result.body);
t.ok(result.statusCode === 200, 'successfully retrieved my own user details');
/* sign in with new email and password */
result = await request.post('/signin', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
email: 'janedoe@gmail.com',
password: 'foobarbazzle'
}
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.user_sid === user_sid, 'successfully signed in with changed email and password');
/* logout */
result = await request.post('/logout', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
email: 'janedoe@gmail.com',
password: 'foobarbazzle'
}
});
//console.log(result.body);
t.ok(result.statusCode === 204, 'successfully logged out');
await sleepFor(1200);
/* using old jwt fails */
result = await request.get(`/Users/me`, {
resolveWithFullResponse: true,
simple: false,
auth: authUser,
});
//console.log(result.body);
t.ok(result.statusCode === 401, 'fails using jwt after logout');
/* sign in again */
result = await request.post('/signin', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
email: 'janedoe@gmail.com',
password: 'foobarbazzle'
}
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.user_sid === user_sid, 'successfully signed in again');
authUser = {bearer: result.body.jwt};
/* new jwt works */
result = await request.get(`/Users/me`, {
resolveWithFullResponse: true,
json: true,
auth: authUser,
});
//console.log(result.body);
t.ok(result.statusCode === 200, 'new jwt works');
/* can not delete a voip_carrier that is not associated to my account */
result = await request.delete('/VoipCarriers/5145b436-2f38-4029-8d4c-fd8c67831c7a', {
resolveWithFullResponse: true,
auth: authUser,
simple: false
});
t.ok(result.statusCode === 422, 'fails to delete a voip_carrier not associated with users account');
/* add a BYOC carrier
Note: no need to supply account_sid, it will be assigned based on the jwt
*/
result = await request.post('/VoipCarriers', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
name: 'BYCO1',
}
});
t.ok(result.statusCode === 201 && result.body.sid, 'succesfully created BYOC carrier');
const carrier_sid = result.body.sid;
/* add a sip gateway to the carrier */
result = await request.post('/SipGateways', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
voip_carrier_sid: carrier_sid,
ipv4: '192.168.1.1',
inbound: true,
outbound: true
}
});
t.ok(result.statusCode === 201, 'successfully created sip gateway for BYOC carrier');
let gateway_sid = result.body.sid;
/* update sip gateway */
result = await request.put(`/SipGateways/${gateway_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
port: 5080
}
});
t.ok(result.statusCode === 204, 'successfully updated sip gateway for BYOC carrier');
/* delete sip gateway */
result = await request.delete(`/SipGateways/${gateway_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
});
t.ok(result.statusCode === 204, 'successfully deleted sip gateway for BYOC carrier');
/* add a smpp gateway to the carrier */
result = await request.post('/SmppGateways', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
voip_carrier_sid: carrier_sid,
ipv4: '192.168.1.1',
inbound: true,
outbound: true
}
});
t.ok(result.statusCode === 201, 'successfully created smpp gateway for BYOC carrier');
gateway_sid = result.body.sid;
/* update smpp gateway */
result = await request.put(`/SmppGateways/${gateway_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
port: 5080
}
});
t.ok(result.statusCode === 204, 'successfully updated smpp gateway for BYOC carrier');
/* delete smpp gateway */
result = await request.delete(`/SmppGateways/${gateway_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
});
t.ok(result.statusCode === 204, 'successfully deleted smpp gateway for BYOC carrier');
result = await request.get('/Sbcs', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.length === 1, 'retrieve Sbcs');
result = await request.get('/Smpps', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.length === 2, 'retrieve Smpps');
/* delete account */
result = await request.delete(`/Accounts/${account_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
});
t.ok(result.statusCode === 204, 'successfully deleted account');
/* create a new user/account using same email/password */
result = await request.post('/register', {
resolveWithFullResponse: true,
json: true,
body: {
service_provider_sid: theOneAndOnlyServiceProviderSid,
provider: 'local',
name: 'Joe User',
email: 'joe@user.com',
password: 'fiddlesticks',
email_activation_code: code
}
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.pristine === true &&
!result.body.is_active && result.body.root_domain === 'sip.yakeeda.com',
'successfully created a user and account and got jwt using email validation');
}
catch (err) {
console.error(err);
t.end(err);
}
});