From 2d9535cac3e5b240b0d7cb5515f251d2bf924a3c Mon Sep 17 00:00:00 2001 From: keithnlarsen Date: Tue, 13 Dec 2011 17:31:28 -0700 Subject: [PATCH 1/4] Added a request helper, and added a gateway which will call backend servers to register for notification events --- .travis.yml | 1 - gateways/notificationRegistrationGateway.js | 37 +++++++++++++++++++ libs/requestHelper.js | 17 +++++++++ .../notificationTypeControllerTest.js | 18 +-------- .../controllers/registrationControllerTest.js | 18 +-------- .../registrationDeviceControllerTest.js | 18 +-------- 6 files changed, 57 insertions(+), 52 deletions(-) create mode 100644 gateways/notificationRegistrationGateway.js create mode 100644 libs/requestHelper.js diff --git a/.travis.yml b/.travis.yml index f1d0f13..2d26206 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ language: node_js node_js: - - 0.4 - 0.6 diff --git a/gateways/notificationRegistrationGateway.js b/gateways/notificationRegistrationGateway.js new file mode 100644 index 0000000..9457541 --- /dev/null +++ b/gateways/notificationRegistrationGateway.js @@ -0,0 +1,37 @@ +module.exports = (function() { + var client; + var reqHelper; + var eventNotificationUrl = 'localhost:3000/events'; + + return { + + init: function( webClient, requestHelper ) { + client = webClient; + reqHelper = requestHelper || require( '../libs/requestHelper' ); + }, + + register: function( registration, notificationType, callBack ) { + var url = require( 'url' ).parse( notificationType.registrationUrl ); + client = client || require( http ).createClient( url.port, url.hostname ); + var request = client.request( 'GET', url.path, {'Host': url.hostname, 'Accept': 'application/json', 'Content-Type': 'application/json'} ); + + var message = { + 'registrationKey': registration.key, + 'eventNotificationUrl': eventNotificationUrl, + 'notificationType': notificationType.name + }; + + request.write( JSON.stringify(message) ); + + reqHelper( request, function( response ) { + switch ( response.statusCode ) { + case 200: + callBack( null, response.body ); + break; + default: + callBack( new Error( 'Error registering notification at:' + notificationType.registrationUrl + '. StatusCode ' + response.statusCode + ': ' + response.body ), null ); + } + } ); + } + } +}()); \ No newline at end of file diff --git a/libs/requestHelper.js b/libs/requestHelper.js new file mode 100644 index 0000000..4b6a3fc --- /dev/null +++ b/libs/requestHelper.js @@ -0,0 +1,17 @@ +module.exports = function( request, callBack ) { + request.on( 'response', function ( response ) { + var responseBody = ""; + response.setEncoding( 'utf8' ); + + response.addListener( "data", function( chunk ) { + responseBody += chunk; + } ); + + response.on( 'end', function() { + response.body = responseBody; + callBack( response ); + } ); + } ); + + request.end(); +}; \ No newline at end of file diff --git a/tests/integration/controllers/notificationTypeControllerTest.js b/tests/integration/controllers/notificationTypeControllerTest.js index ba4b2a1..6bff939 100644 --- a/tests/integration/controllers/notificationTypeControllerTest.js +++ b/tests/integration/controllers/notificationTypeControllerTest.js @@ -9,23 +9,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController var app; var localhost = http.createClient( 3000, 'localhost' ); - var requestHelper = function( request, fn ) { - request.end(); - - request.on( 'response', function ( response ) { - var responseBody = ""; - response.setEncoding( 'utf8' ); - - response.addListener( "data", function( chunk ) { - responseBody += chunk; - } ); - - response.on( 'end', function() { - response.body = responseBody; - fn( response ); - } ); - } ); - }; + var requestHelper = require('../../../libs/requestHelper'); before( function( done ) { var app = require( '../../../app' ); diff --git a/tests/integration/controllers/registrationControllerTest.js b/tests/integration/controllers/registrationControllerTest.js index 9261cab..c243d2d 100644 --- a/tests/integration/controllers/registrationControllerTest.js +++ b/tests/integration/controllers/registrationControllerTest.js @@ -13,23 +13,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f var app; var localhost = http.createClient( 3000, 'localhost' ); - var requestHelper = function( request, fn ) { - request.end(); - - request.on( 'response', function ( response ) { - var responseBody = ""; - response.setEncoding( 'utf8' ); - - response.addListener( "data", function( chunk ) { - responseBody += chunk; - } ); - - response.on( 'end', function() { - response.body = responseBody; - fn( response ); - } ); - } ); - }; + var requestHelper = require('../../../libs/requestHelper'); before( function( done ) { var app = require( '../../../app' ); diff --git a/tests/integration/controllers/registrationDeviceControllerTest.js b/tests/integration/controllers/registrationDeviceControllerTest.js index e11e1bc..e29be2c 100644 --- a/tests/integration/controllers/registrationDeviceControllerTest.js +++ b/tests/integration/controllers/registrationDeviceControllerTest.js @@ -15,23 +15,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll var app; var localhost = http.createClient( 3000, 'localhost' ); - var requestHelper = function( request, fn ) { - request.end(); - - request.on( 'response', function ( response ) { - var responseBody = ""; - response.setEncoding( 'utf8' ); - - response.addListener( "data", function( chunk ) { - responseBody += chunk; - } ); - - response.on( 'end', function() { - response.body = responseBody; - fn( response ); - } ); - } ); - }; + var requestHelper = require('../../../libs/requestHelper'); before( function( done ) { var app = require( '../../../app' ); From e1c421a48c9c06c506f88ab4f9441287aa694301 Mon Sep 17 00:00:00 2001 From: keithnlarsen Date: Tue, 13 Dec 2011 17:50:20 -0700 Subject: [PATCH 2/4] Just fixed up some test names etc. --- routes/index.js | 2 +- .../controllers/registrationDeviceControllerTest.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/routes/index.js b/routes/index.js index 90eb479..3593361 100644 --- a/routes/index.js +++ b/routes/index.js @@ -51,7 +51,7 @@ module.exports = ( function() { app.controllers.notificationType.remove( req, res, next ); } ); - app.get( '/registrations', this.acceptTypeJson, function ( req, res, next ) { + app.get( '/registrations', function ( req, res, next ) { if ( req.accepts( 'json' ) ) { app.controllers.registration.list( req, res, next ); } else { diff --git a/tests/integration/controllers/registrationDeviceControllerTest.js b/tests/integration/controllers/registrationDeviceControllerTest.js index e29be2c..6f1f370 100644 --- a/tests/integration/controllers/registrationDeviceControllerTest.js +++ b/tests/integration/controllers/registrationDeviceControllerTest.js @@ -95,7 +95,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll } ); describe( 'GET to /registrations/:id/devices/:eid', function() { - it( 'should create a second new Device', function( done ) { + it( 'should get a Device given an existing registration id and device id', function( done ) { var request = localhost.request( 'GET', '/registrations/' + registrationId + '/devices/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); requestHelper( request, function( response ) { @@ -156,7 +156,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll } ); describe( 'DELETE to /registrations/:id/devices/:eid', function() { - it( 'should delete device from a registration when called with an existing registration Id and device eid', function( done ) { + it( 'should delete a device from a registration when called with an existing registration id and device id', function( done ) { var request = localhost.request( 'DELETE', '/registrations/' + registrationId + '/devices/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( '{}' ); From 91188b9d711b03bdab6faaa49455ea636463424b Mon Sep 17 00:00:00 2001 From: keithnlarsen Date: Wed, 14 Dec 2011 12:42:31 -0700 Subject: [PATCH 3/4] finished implementing the notificationRegistrationGateway, also starting to implement the Revealing Module Pattern in my code. --- gateways/notificationRegistrationGateway.js | 83 ++++++++----- libs/baseRestController.js | 12 +- libs/requestHandler.js | 25 ++++ libs/requestHelper.js | 17 --- libs/resterrors.js | 6 +- .../notificationTypeControllerTest.js | 20 ++-- .../controllers/registrationControllerTest.js | 18 +-- .../registrationDeviceControllerTest.js | 16 +-- tests/stub.js | 27 +++++ .../notificationRegistrationGatewayTest.js | 112 ++++++++++++++++++ 10 files changed, 257 insertions(+), 79 deletions(-) create mode 100644 libs/requestHandler.js delete mode 100644 libs/requestHelper.js create mode 100644 tests/unit/gateways/notificationRegistrationGatewayTest.js diff --git a/gateways/notificationRegistrationGateway.js b/gateways/notificationRegistrationGateway.js index 9457541..c292b1d 100644 --- a/gateways/notificationRegistrationGateway.js +++ b/gateways/notificationRegistrationGateway.js @@ -1,37 +1,58 @@ +// This is an implementation of the Revealing Module Pattern +// ref: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript +// +// ---- Example of how to call ---- +// ---- You only need to call init if you want to overide the default options ---- +// var options = { client: someClient, requestHandler: someHandler, eventNotificationUrl: 'someUrl' }; +// gateway.init( options ); +// gateway.register( registrationData, voiceMailType, function ( err, success) { ... }); +// module.exports = (function() { var client; - var reqHelper; - var eventNotificationUrl = 'localhost:3000/events'; + var requestHandler = require( '../libs/requestHandler' ); + var eventNotificationUrl = 'http://localhost:3000/events'; - return { + function init ( options ) { + client = options.client || client; + requestHandler = options.requestHandler || requestHandler; + eventNotificationUrl = options.eventNotificationUrl || eventNotificationUrl; + } + + function createRequest ( registration, notificationType ) { + var url = require( 'url' ).parse( notificationType.registrationUrl ); + var http = (url.protocol == 'http') ? require( 'http' ) : require( 'https' ); + + client = client || http.createClient( url.port, url.hostname ); + + var requestOptions = { + 'Host': url.hostname, + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }; - init: function( webClient, requestHelper ) { - client = webClient; - reqHelper = requestHelper || require( '../libs/requestHelper' ); - }, - - register: function( registration, notificationType, callBack ) { - var url = require( 'url' ).parse( notificationType.registrationUrl ); - client = client || require( http ).createClient( url.port, url.hostname ); - var request = client.request( 'GET', url.path, {'Host': url.hostname, 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - - var message = { - 'registrationKey': registration.key, - 'eventNotificationUrl': eventNotificationUrl, - 'notificationType': notificationType.name - }; - - request.write( JSON.stringify(message) ); - - reqHelper( request, function( response ) { - switch ( response.statusCode ) { - case 200: - callBack( null, response.body ); - break; - default: - callBack( new Error( 'Error registering notification at:' + notificationType.registrationUrl + '. StatusCode ' + response.statusCode + ': ' + response.body ), null ); - } - } ); - } + var message = { + 'registrationKey': registration.key, + 'eventNotificationUrl': eventNotificationUrl, + 'notificationType': notificationType.name + }; + + var request = client.request( 'GET', url.path, requestOptions ); + request.write( JSON.stringify( message ) ); + return request; + } + + function register ( registration, notificationType, callBack ) { + requestHandler.handle( createRequest( registration, notificationType ), function( err, response ) { + if ( response.statusCode >= 200 && response.statusCode < 300 ) { + callBack( null, true ); + } else { + callBack( new Error( 'Error registering notification at:' + notificationType.registrationUrl + '. StatusCode ' + response.statusCode + ': ' + response.body ), false ); + } + } ); } + + return { + init: init, + register: register + }; }()); \ No newline at end of file diff --git a/libs/baseRestController.js b/libs/baseRestController.js index 755ea11..15fa3c5 100644 --- a/libs/baseRestController.js +++ b/libs/baseRestController.js @@ -72,7 +72,17 @@ var baseRestController = baseObject.extend( { next( new Error( 'Internal Server Error: see logs for details: ' + err ), req, res ); } } else { - res.send( instance.toObject(), 201 ); + req.params = req.params || {}; + req.params.id = instance._id; + self.getQuery( req ).exec( function( err, instance ) { + if ( err ) { + next( new Error( 'Internal Server Error: see logs for details: ' + err ), req, res ); + } else if ( !instance ) { + next( self.restErrors.notFound.create( self.name + ' Id: "' + req.params.id + '" was not found.' ), req, res ); + } else { + res.send( instance.toObject(), 201 ); + } + } ); } } ); }, diff --git a/libs/requestHandler.js b/libs/requestHandler.js new file mode 100644 index 0000000..5991ad7 --- /dev/null +++ b/libs/requestHandler.js @@ -0,0 +1,25 @@ +module.exports = ( function() { + + function handle( request, callBack ) { + request.on( 'response', function ( response ) { + var responseBody = ""; + response.setEncoding( 'utf8' ); + + response.addListener( "data", function( chunk ) { + responseBody += chunk; + } ); + + response.on( 'end', function() { + response.body = responseBody; + callBack( null, response ); + } ); + } ); + + request.end(); + } + + return { + handle : handle + } +}()); + diff --git a/libs/requestHelper.js b/libs/requestHelper.js deleted file mode 100644 index 4b6a3fc..0000000 --- a/libs/requestHelper.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = function( request, callBack ) { - request.on( 'response', function ( response ) { - var responseBody = ""; - response.setEncoding( 'utf8' ); - - response.addListener( "data", function( chunk ) { - responseBody += chunk; - } ); - - response.on( 'end', function() { - response.body = responseBody; - callBack( response ); - } ); - } ); - - request.end(); -}; \ No newline at end of file diff --git a/libs/resterrors.js b/libs/resterrors.js index d01a0bc..7523966 100644 --- a/libs/resterrors.js +++ b/libs/resterrors.js @@ -45,7 +45,7 @@ module.exports = ( function() { title: 'Unsupported Media Type', description: 'The server is refusing to service the request beacuse the entity of the request is in a format not supported by the requested resource.', httpStatus: 415 - }) + } ) }; var errorMapper = { @@ -67,12 +67,12 @@ module.exports = ( function() { } }; - var errorHandler = function( error, request, response ) { + function errorHandler ( error, request, response ) { var constructorName = error.prototype ? error.prototype.constructor.name : 'default'; var errorHandler = errorMapper[error.name] || errorMapper[constructorName]; errorHandler( error, request, response ); - }; + } return { baseRestError: baseRestError, diff --git a/tests/integration/controllers/notificationTypeControllerTest.js b/tests/integration/controllers/notificationTypeControllerTest.js index 6bff939..65ae373 100644 --- a/tests/integration/controllers/notificationTypeControllerTest.js +++ b/tests/integration/controllers/notificationTypeControllerTest.js @@ -9,7 +9,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController var app; var localhost = http.createClient( 3000, 'localhost' ); - var requestHelper = require('../../../libs/requestHelper'); + var requestHandler = require('../../../libs/requestHandler'); before( function( done ) { var app = require( '../../../app' ); @@ -43,7 +43,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController var request = localhost.request( 'PUT', '/notificationTypes', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( createJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = createJSON; @@ -61,7 +61,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController var request = localhost.request( 'PUT', '/notificationTypes', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( createJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 409 ); response.body.should.match( /duplicate key error/ ); @@ -74,7 +74,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController it( 'should return a single NotificationType when given an existing Id', function( done ) { var request = localhost.request( 'GET', '/notificationTypes/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = createJSON; @@ -90,7 +90,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController it( 'should return 404 NotFound when given a non-existing Id', function( done ) { var request = localhost.request( 'GET', '/notificationTypes/111111111111111111111111', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 404 ); done(); @@ -103,7 +103,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController var request = localhost.request( 'POST', '/notificationTypes/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( updateJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = updateJSON; @@ -121,7 +121,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController var request = localhost.request( 'POST', '/notificationTypes/111111111111111111111111', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( updateJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 404 ); done(); @@ -133,7 +133,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController it( 'should return all NotificationTypes', function( done ) { var request = localhost.request( 'GET', '/notificationTypes', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = updateJSON; @@ -153,7 +153,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController var request = localhost.request( 'DELETE', '/notificationTypes/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write('{}'); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 200 ); done(); @@ -162,7 +162,7 @@ describe( 'Nodification.Tests.Integration.Controllers.NotificationTypeController it( 'should return 404 when called with an Id that doesn\'t exist', function( done ) { var request = localhost.request( 'DELETE', '/notificationTypes/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write('{}'); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 404 ); done(); diff --git a/tests/integration/controllers/registrationControllerTest.js b/tests/integration/controllers/registrationControllerTest.js index c243d2d..d5d9987 100644 --- a/tests/integration/controllers/registrationControllerTest.js +++ b/tests/integration/controllers/registrationControllerTest.js @@ -13,7 +13,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f var app; var localhost = http.createClient( 3000, 'localhost' ); - var requestHelper = require('../../../libs/requestHelper'); + var requestHandler = require('../../../libs/requestHandler'); before( function( done ) { var app = require( '../../../app' ); @@ -59,12 +59,12 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f var request = localhost.request( 'PUT', '/registrations', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( createJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = createJSON; newId = actual._id.toString(); - actual.notificationType.toString().should.equal( voiceMailId ); + actual.notificationType._id.toString().should.equal( voiceMailId ); actual.key.should.equal( expected.key ); actual.registrationConfirmed.should.equal( expected.registrationConfirmed ); actual.devices[0].name.should.equal( expected.devices[0].name ); @@ -81,7 +81,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f it( 'should return a single Registration when given an existing Id', function( done ) { var request = localhost.request( 'GET', '/registrations/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = createJSON; @@ -100,7 +100,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f it( 'should return 404 NotFound when given a non-existing Id', function( done ) { var request = localhost.request( 'GET', '/registrations/111111111111111111111111', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 404 ); done(); @@ -113,7 +113,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f var request = localhost.request( 'POST', '/registrations/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( updateJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = updateJSON; @@ -136,7 +136,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f var request = localhost.request( 'POST', '/registrations/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( updateDevicesJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = updateJSON; var expectedDevices = updateDevicesJSON; @@ -162,7 +162,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f it( 'should return all registrations', function( done ) { var request = localhost.request( 'GET', '/registrations', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = updateJSON; var expectedDevices = updateDevicesJSON; @@ -191,7 +191,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationController', f var request = localhost.request( 'DELETE', '/registrations/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write('{}'); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 200 ); done(); diff --git a/tests/integration/controllers/registrationDeviceControllerTest.js b/tests/integration/controllers/registrationDeviceControllerTest.js index 6f1f370..e18273c 100644 --- a/tests/integration/controllers/registrationDeviceControllerTest.js +++ b/tests/integration/controllers/registrationDeviceControllerTest.js @@ -15,7 +15,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll var app; var localhost = http.createClient( 3000, 'localhost' ); - var requestHelper = require('../../../libs/requestHelper'); + var requestHandler = require('../../../libs/requestHandler'); before( function( done ) { var app = require( '../../../app' ); @@ -63,7 +63,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll var request = localhost.request( 'PUT', '/registrations/' + registrationId + '/devices', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( createJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = createJSON; @@ -80,7 +80,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll var request = localhost.request( 'PUT', '/registrations/' + registrationId + '/devices', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( createJSON2 ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = createJSON2; @@ -98,7 +98,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll it( 'should get a Device given an existing registration id and device id', function( done ) { var request = localhost.request( 'GET', '/registrations/' + registrationId + '/devices/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = createJSON; @@ -117,7 +117,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll var request = localhost.request( 'POST', '/registrations/' + registrationId + '/devices/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( JSON.stringify( updateJSON ) ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = updateJSON; @@ -135,7 +135,7 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll it( 'should get the full list of Devices for a given registration id', function( done ) { var request = localhost.request( 'GET', '/registrations/' + registrationId + '/devices', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); var expected = {}; expected[0] = updateJSON; @@ -160,13 +160,13 @@ describe( 'Nodification.Tests.Integration.Controllers.RegistrationDeviceControll var request = localhost.request( 'DELETE', '/registrations/' + registrationId + '/devices/' + newId, {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); request.write( '{}' ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { response.statusCode.should.equal( 200 ); // Check that it did actually delete the device from the registration var request = localhost.request( 'GET', '/registrations/' + registrationId + '/devices', {'Host': 'localhost', 'Accept': 'application/json', 'Content-Type': 'application/json'} ); - requestHelper( request, function( response ) { + requestHandler.handle( request, function( err, response ) { var actual = JSON.parse( response.body ); actual.should.be.length(1); diff --git a/tests/stub.js b/tests/stub.js index 1486b9f..46a5063 100644 --- a/tests/stub.js +++ b/tests/stub.js @@ -1,3 +1,23 @@ +/** + * Creates a Stub method which you can bind to a mock object for testing purposes. + * + * @param {object} err + * @param {object} callBackValue + * + * Examples: + * + * // You can declare your stub in one of 2 ways + * var mockObject = {}; + * // 1. This will when executed in the method you are testing it assuming it is being called asynchronously + * mockObject.method = new Stub( errValue, callbackValue); + * // 2. This will result in the stub being called synchronously + * mockObject.method = new Stub( returnValue ); + * + * // Inspect your mock later + * mockObject.method.called.withArguments(args); + * mockObject.method.called.withAnyArguments(); + * mockObject.method.called.withNoArguments(); + */ module.exports = function( err, callBackValue ) { var Stub = function() { Stub.args = arguments; @@ -32,7 +52,14 @@ module.exports = function( err, callBackValue ) { if ( typeof arguments[arguments.length - 1] === "function" ) { var callBack = arguments[arguments.length - 1]; callBack( err, callBackValue ); + } else { + if ( err ) { + throw err; + } else { + return callBackValue; + } } + } }; diff --git a/tests/unit/gateways/notificationRegistrationGatewayTest.js b/tests/unit/gateways/notificationRegistrationGatewayTest.js new file mode 100644 index 0000000..2eb62b6 --- /dev/null +++ b/tests/unit/gateways/notificationRegistrationGatewayTest.js @@ -0,0 +1,112 @@ +describe( 'Nodification.Tests.Unit.Gateways.NotificationRegistrationGateway', function() { + + var should = require( 'should' ); + var Stub = require( '../../stub' ); + var registrationGateway = require( '../../../gateways/notificationRegistrationGateway' ); + var mockClient = {}; + var mockRequest = {}; + var mockRequestHandler = {}; + var mockResponse = { statusCode: null, body: '' }; + var mockRegistration = { + key: 'somekey' + }; + var mockNotificationType = { + registrationUrl: 'http://hostname.sjrb.ca/urlpath', + name: 'somename' + }; + + beforeEach( function( done ) { + mockRequest.write = new Stub(); + mockRequestHandler.handle = new Stub(null, mockResponse); + mockClient.request = new Stub(null, mockRequest); + done( ); + } ); + + afterEach( function( done ) { + done( ); + } ); + + describe( '.register( registration, notificationType, callBack )', function() { + it( 'should return sucess when calling registrationUrl for given notificationType and getting http status code 200 back', function( done ) { + + mockResponse.statusCode = 200; + + var options = { + client: mockClient, + requestHandler: mockRequestHandler, + eventNotificationUrl: 'someUrl' + }; + + var message = { + 'registrationKey': mockRegistration.key, + 'eventNotificationUrl': options.eventNotificationUrl, + 'notificationType': mockNotificationType.name + }; + + registrationGateway.init(options); + registrationGateway.register(mockRegistration, mockNotificationType, function (err, success){ + mockRequest.write.called.withAnyArguments(message); + mockRequestHandler.handle.called.withArguments(mockRequest); + mockClient.request.called.withArguments( 'GET', '/urlpath', { 'Host': 'hostname.sjrb.ca', 'Accept': 'application/json', 'Content-Type': 'application/json' } ); + success.should.be.true; + done(err); + }); + + } ); + + it( 'should return sucess when calling registrationUrl for given notificationType and getting http status code 201 back', function( done ) { + + mockResponse.statusCode = 201; + + var options = { + client: mockClient, + requestHandler: mockRequestHandler, + eventNotificationUrl: 'someUrl' + }; + + var message = { + 'registrationKey': mockRegistration.key, + 'eventNotificationUrl': options.eventNotificationUrl, + 'notificationType': mockNotificationType.name + }; + + registrationGateway.init(options); + registrationGateway.register(mockRegistration, mockNotificationType, function (err, success){ + mockRequest.write.called.withAnyArguments(message); + mockRequestHandler.handle.called.withArguments(mockRequest); + mockClient.request.called.withArguments( 'GET', '/urlpath', { 'Host': 'hostname.sjrb.ca', 'Accept': 'application/json', 'Content-Type': 'application/json' } ); + success.should.be.true; + done(err); + }); + + } ); + + it( 'should return error when calling registrationUrl for given notificationType and getting http status code 500 back', function( done ) { + mockResponse.statusCode = 500; + mockResponse.body = 'mock error'; + + var options = { + client: mockClient, + requestHandler: mockRequestHandler, + eventNotificationUrl: 'someUrl' + }; + + var message = { + 'registrationKey': mockRegistration.key, + 'eventNotificationUrl': options.eventNotificationUrl, + 'notificationType': mockNotificationType.name + }; + + registrationGateway.init(options); + registrationGateway.register(mockRegistration, mockNotificationType, function (err, success){ + mockRequest.write.called.withAnyArguments(message); + mockRequestHandler.handle.called.withArguments(mockRequest); + mockClient.request.called.withArguments( 'GET', '/urlpath', { 'Host': 'hostname.sjrb.ca', 'Accept': 'application/json', 'Content-Type': 'application/json' } ); + success.should.be.false; + err.message.should.match(/mock error/); + done(); + }); + + } ); + } ); +} ); \ No newline at end of file From 46d94eb82f6c15c5f480b4737b4fd00bf1c23ab7 Mon Sep 17 00:00:00 2001 From: keithnlarsen Date: Wed, 14 Dec 2011 13:28:05 -0700 Subject: [PATCH 4/4] Just cleaning up some code --- tests/stub.js | 4 +- .../notificationRegistrationGatewayTest.js | 96 +++++++++---------- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/tests/stub.js b/tests/stub.js index 46a5063..b9de7ed 100644 --- a/tests/stub.js +++ b/tests/stub.js @@ -27,7 +27,7 @@ module.exports = function( err, callBackValue ) { withArguments: function() { for ( var i = 0; i < arguments.length; i ++ ) { if ( JSON.stringify( Stub.args[i] ) !== JSON.stringify( arguments[i] ) ) { - throw new Error( " Actual arguments: " + JSON.stringify( Stub.args[i] ) + " does not match expected: " + JSON.stringify( arguments[i] ) ); + throw new Error( ' Actual arguments: ' + JSON.stringify( Stub.args[i] ) + ' does not match expected: ' + JSON.stringify( arguments[i] ) ); } } return true; @@ -49,7 +49,7 @@ module.exports = function( err, callBackValue ) { }; if ( arguments.length > 0 ) { - if ( typeof arguments[arguments.length - 1] === "function" ) { + if ( typeof arguments[arguments.length - 1] === 'function' ) { var callBack = arguments[arguments.length - 1]; callBack( err, callBackValue ); } else { diff --git a/tests/unit/gateways/notificationRegistrationGatewayTest.js b/tests/unit/gateways/notificationRegistrationGatewayTest.js index 2eb62b6..cb5fe68 100644 --- a/tests/unit/gateways/notificationRegistrationGatewayTest.js +++ b/tests/unit/gateways/notificationRegistrationGatewayTest.js @@ -14,16 +14,17 @@ describe( 'Nodification.Tests.Unit.Gateways.NotificationRegistrationGateway', fu registrationUrl: 'http://hostname.sjrb.ca/urlpath', name: 'somename' }; + var eventNotificationUrl = 'http://localhost/events'; beforeEach( function( done ) { mockRequest.write = new Stub(); - mockRequestHandler.handle = new Stub(null, mockResponse); - mockClient.request = new Stub(null, mockRequest); - done( ); + mockRequestHandler.handle = new Stub( null, mockResponse ); + mockClient.request = new Stub( null, mockRequest ); + done(); } ); afterEach( function( done ) { - done( ); + done(); } ); describe( '.register( registration, notificationType, callBack )', function() { @@ -31,26 +32,25 @@ describe( 'Nodification.Tests.Unit.Gateways.NotificationRegistrationGateway', fu mockResponse.statusCode = 200; - var options = { - client: mockClient, - requestHandler: mockRequestHandler, - eventNotificationUrl: 'someUrl' - }; - - var message = { + var expectedMessage = { 'registrationKey': mockRegistration.key, - 'eventNotificationUrl': options.eventNotificationUrl, + 'eventNotificationUrl': eventNotificationUrl, 'notificationType': mockNotificationType.name }; - registrationGateway.init(options); - registrationGateway.register(mockRegistration, mockNotificationType, function (err, success){ - mockRequest.write.called.withAnyArguments(message); - mockRequestHandler.handle.called.withArguments(mockRequest); + registrationGateway.init( { + client: mockClient, + requestHandler: mockRequestHandler, + eventNotificationUrl: eventNotificationUrl + } ); + + registrationGateway.register( mockRegistration, mockNotificationType, function ( err, success ) { + mockRequest.write.called.withArguments( JSON.stringify( expectedMessage ) ); + mockRequestHandler.handle.called.withArguments( mockRequest ); mockClient.request.called.withArguments( 'GET', '/urlpath', { 'Host': 'hostname.sjrb.ca', 'Accept': 'application/json', 'Content-Type': 'application/json' } ); - success.should.be.true; - done(err); - }); + success.should.equal(true); + done( err ); + } ); } ); @@ -58,26 +58,25 @@ describe( 'Nodification.Tests.Unit.Gateways.NotificationRegistrationGateway', fu mockResponse.statusCode = 201; - var options = { - client: mockClient, - requestHandler: mockRequestHandler, - eventNotificationUrl: 'someUrl' - }; - - var message = { + var expectedMessage = { 'registrationKey': mockRegistration.key, - 'eventNotificationUrl': options.eventNotificationUrl, + 'eventNotificationUrl': eventNotificationUrl, 'notificationType': mockNotificationType.name }; - registrationGateway.init(options); - registrationGateway.register(mockRegistration, mockNotificationType, function (err, success){ - mockRequest.write.called.withAnyArguments(message); - mockRequestHandler.handle.called.withArguments(mockRequest); + registrationGateway.init( { + client: mockClient, + requestHandler: mockRequestHandler, + eventNotificationUrl: eventNotificationUrl + } ); + + registrationGateway.register( mockRegistration, mockNotificationType, function ( err, success ) { + mockRequest.write.called.withArguments( JSON.stringify( expectedMessage ) ); + mockRequestHandler.handle.called.withArguments( mockRequest ); mockClient.request.called.withArguments( 'GET', '/urlpath', { 'Host': 'hostname.sjrb.ca', 'Accept': 'application/json', 'Content-Type': 'application/json' } ); - success.should.be.true; - done(err); - }); + success.should.equal(true); + done( err ); + } ); } ); @@ -85,27 +84,26 @@ describe( 'Nodification.Tests.Unit.Gateways.NotificationRegistrationGateway', fu mockResponse.statusCode = 500; mockResponse.body = 'mock error'; - var options = { - client: mockClient, - requestHandler: mockRequestHandler, - eventNotificationUrl: 'someUrl' - }; - - var message = { + var expectedMessage = { 'registrationKey': mockRegistration.key, - 'eventNotificationUrl': options.eventNotificationUrl, + 'eventNotificationUrl': eventNotificationUrl, 'notificationType': mockNotificationType.name }; - registrationGateway.init(options); - registrationGateway.register(mockRegistration, mockNotificationType, function (err, success){ - mockRequest.write.called.withAnyArguments(message); - mockRequestHandler.handle.called.withArguments(mockRequest); + registrationGateway.init( { + client: mockClient, + requestHandler: mockRequestHandler, + eventNotificationUrl: eventNotificationUrl + } ); + + registrationGateway.register( mockRegistration, mockNotificationType, function ( err, success ) { + mockRequest.write.called.withArguments( JSON.stringify( expectedMessage ) ); + mockRequestHandler.handle.called.withArguments( mockRequest ); mockClient.request.called.withArguments( 'GET', '/urlpath', { 'Host': 'hostname.sjrb.ca', 'Accept': 'application/json', 'Content-Type': 'application/json' } ); - success.should.be.false; - err.message.should.match(/mock error/); + success.should.equal(false); + err.message.should.match( /mock error/ ); done(); - }); + } ); } ); } );