diff --git a/.jshintrc b/.jshintrc index 1092da4..0994b4c 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,52 +1,51 @@ { - "indent": 4, - "strict": true, - "globalstrict": true, - "node": true, - "browser": true, - "nonew": true, - "curly": true, - "eqeqeq": true, - "immed": true, - "newcap": true, - "regexp": true, - "evil": true, - "eqnull": true, - "expr": true, - "trailing": true, - "undef": true, - "unused": true, + "indent": 4, + "strict": true, + "globalstrict": true, + "node": true, + "browser": true, + "nonew": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "newcap": true, + "regexp": true, + "evil": true, + "eqnull": true, + "expr": true, + "trailing": true, + "undef": true, + "unused": true, - "predef": [ - "$", - "inject", - "Promise", - "self", - "importScripts", - "console", - "process", - "chrome", - "Notification", - "Event", - "sinon", - "mocha", - "chai", - "expect", - "describe", - "it", - "before", - "beforeEach", - "after", - "afterEach", - "FastClick", - "angular", - "forge", - "Lawnchair", - "_", - "openpgp", - "qMock" - ], + "predef": [ + "$", + "inject", + "Promise", + "qMock", + "self", + "importScripts", + "console", + "process", + "chrome", + "Notification", + "Event", + "sinon", + "mocha", + "chai", + "expect", + "describe", + "it", + "before", + "beforeEach", + "after", + "afterEach", + "FastClick", + "angular", + "forge", + "Lawnchair", + "_", + "openpgp" + ], - "globals": { - } + "globals": {} } \ No newline at end of file diff --git a/src/js/service/invitation.js b/src/js/service/invitation.js index 96e380f..5db1fbe 100644 --- a/src/js/service/invitation.js +++ b/src/js/service/invitation.js @@ -8,18 +8,11 @@ module.exports = Invitation; * The Invitation is a high level Data Access Object that access the invitation service REST endpoint. * @param {Object} restDao The REST Data Access Object abstraction */ -function Invitation(invitationRestDao) { +function Invitation(invitationRestDao, $q) { this._restDao = invitationRestDao; + this._q = $q; } -// -// Constants -// - -Invitation.INVITE_MISSING = 1; -Invitation.INVITE_PENDING = 2; -Invitation.INVITE_SUCCESS = 4; - // // API // @@ -28,35 +21,18 @@ Invitation.INVITE_SUCCESS = 4; * Notes an invite for the recipient by the sender in the invitation web service * @param {String} options.recipient User ID of the recipient * @param {String} options.sender User ID of the sender - * @param {Function} callback(error, status) Returns information if the invitation worked (INVITE_SUCCESS), if an invitation is already pendin (INVITE_PENDING), or information if an error occurred. + * @return {Promise} */ -Invitation.prototype.invite = function(options, callback) { - if (typeof options !== 'object' || typeof options.recipient !== 'string' || typeof options.recipient !== 'string') { - callback({ - errMsg: 'erroneous usage of api: incorrect parameters!' - }); - return; - } - - var uri = '/invitation/recipient/' + options.recipient + '/sender/' + options.sender; - this._restDao.put({}, uri, completed); - - function completed(error, res, status) { - if (error) { - callback(error); - return; +Invitation.prototype.invite = function(options) { + var self = this; + return self._q(function(resolve) { + if (typeof options !== 'object' || typeof options.recipient !== 'string' || typeof options.sender !== 'string') { + throw new Error('erroneous usage of api: incorrect parameters!'); } + resolve(); - if (status === 201) { - callback(null, Invitation.INVITE_SUCCESS); - return; - } else if (status === 304) { - callback(null, Invitation.INVITE_PENDING); - return; - } - - callback({ - errMsg: 'unexpected invitation state' - }); - } + }).then(function() { + var uri = '/invitation/recipient/' + options.recipient + '/sender/' + options.sender; + return self._restDao.put({}, uri); + }); }; \ No newline at end of file diff --git a/src/js/service/rest.js b/src/js/service/rest.js index 393a1f2..b281fc9 100644 --- a/src/js/service/rest.js +++ b/src/js/service/rest.js @@ -98,15 +98,15 @@ RestDAO.prototype.remove = function(uri) { // RestDAO.prototype._processRequest = function(options) { - return this._q(function(resolve, reject) { + var self = this; + return self._q(function(resolve, reject) { var xhr, format; if (typeof options.uri === 'undefined') { - reject({ + throw { code: 400, message: 'Bad Request! URI is a mandatory parameter.' - }); - return; + }; } options.type = options.type || 'json'; @@ -118,15 +118,14 @@ RestDAO.prototype._processRequest = function(options) { } else if (options.type === 'text') { format = 'text/plain'; } else { - reject({ + throw { code: 400, message: 'Bad Request! Unhandled data type.' - }); - return; + }; } xhr = new XMLHttpRequest(); - xhr.open(options.method, this._baseUri + options.uri); + xhr.open(options.method, self._baseUri + options.uri); xhr.setRequestHeader('Accept', format); xhr.setRequestHeader('Content-Type', format); @@ -140,7 +139,7 @@ RestDAO.prototype._processRequest = function(options) { res = xhr.responseText; } - resolve(res, xhr.status); + resolve(res); return; } diff --git a/test/unit/service/invitation-dao-test.js b/test/unit/service/invitation-dao-test.js index b8b4237..a47be58 100644 --- a/test/unit/service/invitation-dao-test.js +++ b/test/unit/service/invitation-dao-test.js @@ -1,8 +1,7 @@ 'use strict'; var RestDAO = require('../../../src/js/service/rest'), - InvitationDAO = require('../../../src/js/service/invitation'), - appConfig = require('../../../src/js/app-config'); + InvitationDAO = require('../../../src/js/service/invitation'); describe('Invitation DAO unit tests', function() { var restDaoStub, invitationDao, @@ -12,94 +11,80 @@ describe('Invitation DAO unit tests', function() { beforeEach(function() { restDaoStub = sinon.createStubInstance(RestDAO); - invitationDao = new InvitationDAO(restDaoStub, appConfig); + invitationDao = new InvitationDAO(restDaoStub, window.qMock); }); describe('initialization', function() { it('should wire up correctly', function() { expect(invitationDao._restDao).to.equal(restDaoStub); expect(invitationDao.invite).to.exist; - expect(InvitationDAO.INVITE_MISSING).to.equal(1); - expect(InvitationDAO.INVITE_PENDING).to.equal(2); - expect(InvitationDAO.INVITE_SUCCESS).to.equal(4); }); }); describe('invite', function() { it('should invite the recipient', function(done) { - restDaoStub.put.yieldsAsync(null, undefined, 201); + restDaoStub.put.returns(new Promise(function(res) { + res(); + })); invitationDao.invite({ recipient: alice, sender: bob - }, function(err, status) { - expect(err).to.not.exist; - expect(status).to.equal(InvitationDAO.INVITE_SUCCESS); + }).then(function() { expect(restDaoStub.put.calledWith({}, expectedUri)).to.be.true; done(); }); }); - it('should point out already invited recipient', function(done) { - restDaoStub.put.yieldsAsync(null, undefined, 304); - - invitationDao.invite({ - recipient: alice, - sender: bob - }, function(err, status) { - expect(err).to.not.exist; - expect(status).to.equal(InvitationDAO.INVITE_PENDING); - done(); - }); - }); - it('should not work for http error', function(done) { - restDaoStub.put.yieldsAsync({ - errMsg: 'jawollja.' - }); + restDaoStub.put.throws(new Error()); invitationDao.invite({ recipient: alice, sender: bob - }, function(err, status) { + }).catch(function(err) { expect(err).to.exist; - expect(status).to.not.exist; done(); }); }); - it('should not work for unexpected response', function(done) { - restDaoStub.put.yieldsAsync(null, undefined, 1337); - + it('should report erroneous usage', function(done) { invitationDao.invite({ - recipient: alice, sender: bob - }, function(err, status) { + }, expectError); + + invitationDao.invite('asd').catch(expectError); + + function expectError(err) { expect(err).to.exist; - expect(status).to.not.exist; done(); - }); + } }); - it('should report erroneous usage', function() { - invitationDao.invite({ - sender: bob - }, expectError); - + it('should report erroneous usage', function(done) { invitationDao.invite({ recipient: alice, }, expectError); + invitationDao.invite('asd').catch(expectError); + + function expectError(err) { + expect(err).to.exist; + done(); + } + }); + + it('should report erroneous usage', function(done) { invitationDao.invite({ recipient: 123, sender: 123 }, expectError); - invitationDao.invite('asd', expectError); + invitationDao.invite('asd').catch(expectError); - function expectError(err, status) { + function expectError(err) { expect(err).to.exist; - expect(status).to.not.exist; + done(); } }); }); diff --git a/test/unit/service/rest-dao-test.js b/test/unit/service/rest-dao-test.js index c8ca3a6..7dd1638 100644 --- a/test/unit/service/rest-dao-test.js +++ b/test/unit/service/rest-dao-test.js @@ -7,7 +7,7 @@ describe('Rest DAO unit tests', function() { var restDao, xhrMock, requests; beforeEach(function() { - restDao = new RestDAO(); + restDao = new RestDAO(window.qMock); xhrMock = sinon.useFakeXMLHttpRequest(); requests = []; @@ -23,7 +23,7 @@ describe('Rest DAO unit tests', function() { describe('setBaseUri', function() { it('should accept base uri', function() { var baseUri = 'http://custom.com'; - restDao = new RestDAO(); + restDao = new RestDAO(window.qMock); expect(restDao._baseUri).to.not.exist; restDao.setBaseUri(baseUri); expect(restDao._baseUri).to.equal(baseUri); @@ -31,15 +31,14 @@ describe('Rest DAO unit tests', function() { }); describe('get', function() { - it('should work with json as default type', function() { + it('should work with json as default type', function(done) { restDao.get({ uri: '/asdf' - }, function(err, data, status) { - expect(err).to.not.exist; + }).then(function(data) { expect(data.foo).to.equal('bar'); var req = requests[0]; expect(req.requestHeaders.Accept).to.equal('application/json'); - expect(status).to.equal(200); + done(); }); expect(requests.length).to.equal(1); @@ -48,16 +47,15 @@ describe('Rest DAO unit tests', function() { }, '{"foo": "bar"}'); }); - it('should work with jsonz', function() { + it('should work with jsonz', function(done) { restDao.get({ uri: '/asdf', type: 'json' - }, function(err, data, status) { - expect(err).to.not.exist; + }).then(function(data) { expect(data.foo).to.equal('bar'); var req = requests[0]; expect(req.requestHeaders.Accept).to.equal('application/json'); - expect(status).to.equal(200); + done(); }); expect(requests.length).to.equal(1); @@ -66,16 +64,15 @@ describe('Rest DAO unit tests', function() { }, '{"foo": "bar"}'); }); - it('should work with plain text', function() { + it('should work with plain text', function(done) { restDao.get({ uri: '/asdf', type: 'text' - }, function(err, data, status) { - expect(err).to.not.exist; + }).then(function(data) { expect(data).to.equal('foobar!'); var req = requests[0]; expect(req.requestHeaders.Accept).to.equal('text/plain'); - expect(status).to.equal(200); + done(); }); expect(requests.length).to.equal(1); @@ -84,16 +81,15 @@ describe('Rest DAO unit tests', function() { }, 'foobar!'); }); - it('should work with xml', function() { + it('should work with xml', function(done) { restDao.get({ uri: '/asdf', type: 'xml' - }, function(err, data, status) { - expect(err).to.not.exist; + }).then(function(data) { expect(data).to.equal('bar'); var req = requests[0]; expect(req.requestHeaders.Accept).to.equal('application/xml'); - expect(status).to.equal(200); + done(); }); expect(requests.length).to.equal(1); @@ -102,32 +98,29 @@ describe('Rest DAO unit tests', function() { }, 'bar'); }); - it('should fail for missing uri parameter', function() { - restDao.get({}, function(err, data) { - expect(err).to.exist; + it('should fail for missing uri parameter', function(done) { + restDao.get({}).catch(function(err) { expect(err.code).to.equal(400); - expect(data).to.not.exist; + done(); }); }); - it('should fail for unhandled data type', function() { + it('should fail for unhandled data type', function(done) { restDao.get({ uri: '/asdf', type: 'snafu' - }, function(err, data) { - expect(err).to.exist; + }).catch(function(err) { expect(err.code).to.equal(400); - expect(data).to.not.exist; + done(); }); }); - it('should fail for server error', function() { + it('should fail for server error', function(done) { restDao.get({ uri: '/asdf' - }, function(err, data) { - expect(err).to.exist; + }).catch(function(err) { expect(err.code).to.equal(500); - expect(data).to.not.exist; + done(); }); expect(requests.length).to.equal(1); @@ -138,10 +131,10 @@ describe('Rest DAO unit tests', function() { }); describe('post', function() { - it('should fail', function() { - restDao.post('/asdf', {}, function(err) { - expect(err).to.exist; + it('should fail', function(done) { + restDao.post('/asdf', {}).catch(function(err) { expect(err.code).to.equal(500); + done(); }); expect(requests.length).to.equal(1); @@ -150,11 +143,10 @@ describe('Rest DAO unit tests', function() { }, 'Internal error'); }); - it('should work', function() { - restDao.post('/asdf', {}, function(err, res, status) { - expect(err).to.not.exist; + it('should work', function(done) { + restDao.post('/asdf', {}).then(function(res) { expect(res).to.equal(''); - expect(status).to.equal(201); + done(); }); expect(requests.length).to.equal(1); @@ -163,10 +155,10 @@ describe('Rest DAO unit tests', function() { }); describe('put', function() { - it('should fail', function() { - restDao.put('/asdf', {}, function(err) { - expect(err).to.exist; + it('should fail', function(done) { + restDao.put('/asdf', {}).catch(function(err) { expect(err.code).to.equal(500); + done(); }); expect(requests.length).to.equal(1); @@ -175,11 +167,10 @@ describe('Rest DAO unit tests', function() { }, 'Internal error'); }); - it('should work', function() { - restDao.put('/asdf', {}, function(err, res, status) { - expect(err).to.not.exist; + it('should work', function(done) { + restDao.put('/asdf', {}).then(function(res) { expect(res).to.equal(''); - expect(status).to.equal(201); + done(); }); expect(requests.length).to.equal(1); @@ -188,10 +179,10 @@ describe('Rest DAO unit tests', function() { }); describe('remove', function() { - it('should fail', function() { - restDao.remove('/asdf', function(err) { - expect(err).to.exist; + it('should fail', function(done) { + restDao.remove('/asdf').catch(function(err) { expect(err.code).to.equal(500); + done(); }); expect(requests.length).to.equal(1); @@ -200,11 +191,10 @@ describe('Rest DAO unit tests', function() { }, 'Internal error'); }); - it('should work', function() { - restDao.remove('/asdf', function(err, res, status) { - expect(err).to.not.exist; + it('should work', function(done) { + restDao.remove('/asdf').then(function(res) { expect(res).to.equal(''); - expect(status).to.equal(200); + done(); }); expect(requests.length).to.equal(1);