Skip to content

Commit

Permalink
Update Twilio sample + add (unit) tests (#1268)
Browse files Browse the repository at this point in the history
* Update Twilio sample + add tests

* Remove linter
  • Loading branch information
Ace Nassri authored May 13, 2019
1 parent dc69ebf commit ee42b35
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 24 deletions.
47 changes: 25 additions & 22 deletions appengine/twilio/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016, Google, Inc.
* Copyright 2019, Google LLC.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
Expand All @@ -15,7 +15,6 @@

'use strict';

const format = require('util').format;
const express = require('express');
const bodyParser = require('body-parser').urlencoded({
extended: false,
Expand All @@ -33,12 +32,14 @@ if (!TWILIO_NUMBER) {
);
}

const twilio = require('twilio')(
const Twilio = require('twilio');

const twilioClient = Twilio(
process.env.TWILIO_ACCOUNT_SID,
process.env.TWILIO_AUTH_TOKEN
);

const TwimlResponse = require('twilio').TwimlResponse;
const TwimlResponse = Twilio.TwimlResponse;

// [START gae_flex_twilio_receive_call]
app.post('/call/receive', (req, res) => {
Expand All @@ -53,7 +54,7 @@ app.post('/call/receive', (req, res) => {
// [END gae_flex_twilio_receive_call]

// [START gae_flex_twilio_send_sms]
app.get('/sms/send', (req, res, next) => {
app.get('/sms/send', async (req, res, next) => {
const to = req.query.to;
if (!to) {
res
Expand All @@ -62,20 +63,18 @@ app.get('/sms/send', (req, res, next) => {
return;
}

twilio.sendMessage(
{
try {
await twilioClient.messages.create({
to: to,
from: TWILIO_NUMBER,
body: 'Hello from Google App Engine',
},
err => {
if (err) {
next(err);
return;
}
res.status(200).send('Message sent.');
}
);
});
console.log('BAZ!');
res.status(200).send('Message sent.');
} catch (err) {
next(err);
return;
}
});
// [END gae_flex_twilio_send_sms]

Expand All @@ -85,7 +84,7 @@ app.post('/sms/receive', bodyParser, (req, res) => {
const body = req.body.Body;

const resp = new TwimlResponse();
resp.message(format('Hello, %s, you said: %s', sender, body));
resp.message(`Hello, ${sender}, you said: ${body}`);

res
.status(200)
Expand All @@ -95,8 +94,12 @@ app.post('/sms/receive', bodyParser, (req, res) => {
// [END gae_flex_twilio_receive_sms]

// Start the server
const PORT = process.env.PORT;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
if (module === require.main) {
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
}

exports.app = app;
12 changes: 10 additions & 2 deletions appengine/twilio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@
"node": ">=8"
},
"scripts": {
"start": "node app.js"
"start": "node app.js",
"test": "mocha test/*.test.js"
},
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4",
"twilio": "^3.28.0"
"twilio": "^3.30.3"
},
"devDependencies": {
"assert": "^1.4.1",
"mocha": "^6.1.4",
"proxyquire": "^2.1.0",
"sinon": "^7.3.2",
"supertest": "^4.0.2"
}
}
83 changes: 83 additions & 0 deletions appengine/twilio/test/app.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Copyright 2019, Google LLC.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const assert = require('assert');
const Supertest = require('supertest');
const sinon = require('sinon');
const proxyquire = require('proxyquire').noCallThru();

const getSample = () => {
const twilioMock = {
messages: {
create: sinon.stub().resolves(),
},
message: sinon.stub(),
say: sinon.stub(),
toString: sinon.stub(),
};

const twilioStub = sinon.stub().returns(twilioMock);
twilioStub.TwimlResponse = sinon.stub().returns(twilioMock);

const {app} = proxyquire('../app', {twilio: twilioStub});

return {
supertest: Supertest(app, {
twilio: twilioStub,
}),
mocks: {
twilio: twilioMock,
},
};
};

it('should send an SMS message', async () => {
const {supertest} = getSample();

return supertest
.get('/sms/send')
.query({to: 1234})
.expect(200)
.expect(response => {
assert.strictEqual(response.text, 'Message sent.');
});
});

it('should receive an SMS message', async () => {
const {supertest, mocks} = getSample();

return supertest
.post('/sms/receive')
.send({From: 'Bob', Body: 'hi'})
.type('form')
.expect(200)
.expect(() => {
assert(mocks.twilio.message.calledWith('Hello, Bob, you said: hi'));
});
});

it('should receive a call', async () => {
const {supertest, mocks} = getSample();

return supertest
.post('/call/receive')
.send()
.expect(200)
.expect(() => {
assert(mocks.twilio.say.calledWith('Hello from Google App Engine.'));
});
});

0 comments on commit ee42b35

Please sign in to comment.