From 513c9922817a90c5853d32ee574506d1e82e4083 Mon Sep 17 00:00:00 2001 From: ace-n Date: Tue, 7 May 2019 16:59:06 -0700 Subject: [PATCH 1/2] Update Twilio sample + add tests --- appengine/twilio/app.js | 47 +++++++++-------- appengine/twilio/package.json | 18 ++++++- appengine/twilio/test/app.test.js | 83 +++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 24 deletions(-) create mode 100644 appengine/twilio/test/app.test.js diff --git a/appengine/twilio/app.js b/appengine/twilio/app.js index 2277a6eb1e..a70c2784a8 100644 --- a/appengine/twilio/app.js +++ b/appengine/twilio/app.js @@ -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 @@ -15,7 +15,6 @@ 'use strict'; -const format = require('util').format; const express = require('express'); const bodyParser = require('body-parser').urlencoded({ extended: false, @@ -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) => { @@ -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 @@ -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] @@ -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) @@ -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; diff --git a/appengine/twilio/package.json b/appengine/twilio/package.json index ed84484a0f..d08a1a770a 100644 --- a/appengine/twilio/package.json +++ b/appengine/twilio/package.json @@ -9,11 +9,25 @@ "node": ">=8" }, "scripts": { - "start": "node app.js" + "start": "node app.js", + "lint": "eslint *.js test/*.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", + "eslint": "^5.16.0", + "eslint-config-prettier": "^4.2.0", + "eslint-plugin-node": "^8.0.1", + "eslint-plugin-prettier": "^3.0.1", + "mocha": "^6.1.4", + "prettier": "^1.17.0", + "proxyquire": "^2.1.0", + "sinon": "^7.3.2", + "supertest": "^4.0.2" } } diff --git a/appengine/twilio/test/app.test.js b/appengine/twilio/test/app.test.js new file mode 100644 index 0000000000..58e4a29960 --- /dev/null +++ b/appengine/twilio/test/app.test.js @@ -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.')); + }); +}); From cf3f4d16a5514d4b262e4b2a5518ba496eb38565 Mon Sep 17 00:00:00 2001 From: ace-n Date: Wed, 8 May 2019 10:15:21 -0700 Subject: [PATCH 2/2] Remove linter --- appengine/twilio/package.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/appengine/twilio/package.json b/appengine/twilio/package.json index d08a1a770a..d33fa89a53 100644 --- a/appengine/twilio/package.json +++ b/appengine/twilio/package.json @@ -10,7 +10,6 @@ }, "scripts": { "start": "node app.js", - "lint": "eslint *.js test/*.js", "test": "mocha test/*.test.js" }, "dependencies": { @@ -20,12 +19,7 @@ }, "devDependencies": { "assert": "^1.4.1", - "eslint": "^5.16.0", - "eslint-config-prettier": "^4.2.0", - "eslint-plugin-node": "^8.0.1", - "eslint-plugin-prettier": "^3.0.1", "mocha": "^6.1.4", - "prettier": "^1.17.0", "proxyquire": "^2.1.0", "sinon": "^7.3.2", "supertest": "^4.0.2"