mirror of
https://github.com/moparisthebest/mail
synced 2025-02-16 15:10:10 -05:00
[WO-61] introduce invitation DAO
This commit is contained in:
parent
e71ee471f6
commit
6ad8683380
@ -1,9 +1,92 @@
|
|||||||
define(function() {
|
define(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The InvitationDAO is a high level Data Access Object that access the invitation service REST endpoint.
|
||||||
|
* @param {Object} restDao The REST Data Access Object abstraction
|
||||||
|
*/
|
||||||
var InvitationDAO = function(restDao) {
|
var InvitationDAO = function(restDao) {
|
||||||
this._restDao = restDao;
|
this._restDao = restDao;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constants
|
||||||
|
//
|
||||||
|
|
||||||
|
InvitationDAO.INVITE_MISSING = 1;
|
||||||
|
InvitationDAO.INVITE_PENDING = 2;
|
||||||
|
InvitationDAO.INVITE_SUCCESS = 4;
|
||||||
|
|
||||||
|
//
|
||||||
|
// API
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notes an invite for the recipient by the sender in the invitation web service
|
||||||
|
* @param {String} recipient User ID of the recipient
|
||||||
|
* @param {String} 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.
|
||||||
|
*/
|
||||||
|
InvitationDAO.prototype.invite = function(recipient, sender, callback) {
|
||||||
|
this._restDao.put(null, uri(recipient, sender), completed);
|
||||||
|
|
||||||
|
function completed(error, res, status) {
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 201) {
|
||||||
|
callback(null, InvitationDAO.INVITE_SUCCESS);
|
||||||
|
return;
|
||||||
|
} else if (status === 304) {
|
||||||
|
callback(null, InvitationDAO.INVITE_PENDING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback({
|
||||||
|
errMsg: 'unexpected invitation state'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an invitation for the recipient by the sender is present in the invitation web service
|
||||||
|
* @param {String} recipient User ID of the recipient
|
||||||
|
* @param {String} sender User ID of the sender
|
||||||
|
* @param {Function} callback(error, status) Returns information about the invitation status, either an invitation is already on place (INVITE_PENDING), or not (INVITE_MISSING), or information if an error occurred.
|
||||||
|
*/
|
||||||
|
InvitationDAO.prototype.check = function(recipient, sender, callback) {
|
||||||
|
this._restDao.get(null, uri(recipient, sender), completed);
|
||||||
|
|
||||||
|
function completed(error, res, status) {
|
||||||
|
// 404 is a meaningful return value from the web service
|
||||||
|
if (error && error.code !== 404) {
|
||||||
|
callback(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error && error.code === 404) {
|
||||||
|
callback(null, InvitationDAO.INVITE_MISSING);
|
||||||
|
return;
|
||||||
|
} else if (status === 200) {
|
||||||
|
callback(null, InvitationDAO.INVITE_PENDING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback({
|
||||||
|
errMsg: 'unexpected invitation state'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper functions
|
||||||
|
//
|
||||||
|
|
||||||
|
function uri(a, b) {
|
||||||
|
return '/invitation/recipient/' + a + '/sender/' + b;
|
||||||
|
}
|
||||||
|
|
||||||
return InvitationDAO;
|
return InvitationDAO;
|
||||||
});
|
});
|
@ -51,8 +51,8 @@ define(function(require) {
|
|||||||
headers: {
|
headers: {
|
||||||
'Accept': acceptHeader
|
'Accept': acceptHeader
|
||||||
},
|
},
|
||||||
success: function(res) {
|
success: function(res, textStatus, xhr) {
|
||||||
callback(null, res);
|
callback(null, res, xhr.status);
|
||||||
},
|
},
|
||||||
error: function(xhr, textStatus, err) {
|
error: function(xhr, textStatus, err) {
|
||||||
callback({
|
callback({
|
||||||
@ -73,8 +73,8 @@ define(function(require) {
|
|||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
data: JSON.stringify(item),
|
data: JSON.stringify(item),
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
success: function() {
|
success: function(res, textStatus, xhr) {
|
||||||
callback();
|
callback(null, res, xhr.status);
|
||||||
},
|
},
|
||||||
error: function(xhr, textStatus, err) {
|
error: function(xhr, textStatus, err) {
|
||||||
callback({
|
callback({
|
||||||
@ -93,8 +93,8 @@ define(function(require) {
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: this._baseUri + uri,
|
url: this._baseUri + uri,
|
||||||
type: 'DELETE',
|
type: 'DELETE',
|
||||||
success: function() {
|
success: function(res, textStatus, xhr) {
|
||||||
callback();
|
callback(null, res, xhr.status);
|
||||||
},
|
},
|
||||||
error: function(xhr, textStatus, err) {
|
error: function(xhr, textStatus, err) {
|
||||||
callback({
|
callback({
|
||||||
|
122
test/new-unit/invitation-dao-test.js
Normal file
122
test/new-unit/invitation-dao-test.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
define(function(require) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var RestDAO = require('js/dao/rest-dao'),
|
||||||
|
InvitationDAO = require('js/dao/invitation-dao'),
|
||||||
|
expect = chai.expect;
|
||||||
|
|
||||||
|
describe('Invitation DAO unit tests', function() {
|
||||||
|
var restDaoStub, invitationDao,
|
||||||
|
alice = 'zuhause@aol.com',
|
||||||
|
bob = 'manfred.mustermann@musterdomain.com',
|
||||||
|
expectedUri = '/invitation/recipient/' + alice + '/sender/' + bob;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
restDaoStub = sinon.createStubInstance(RestDAO);
|
||||||
|
invitationDao = new InvitationDAO(restDaoStub);
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
invitationDao.invite(alice, bob, function(err, status) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(status).to.equal(InvitationDAO.INVITE_SUCCESS);
|
||||||
|
expect(restDaoStub.put.calledWith(null, expectedUri)).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should point out already invited recipient', function(done) {
|
||||||
|
restDaoStub.put.yieldsAsync(null, undefined, 304);
|
||||||
|
|
||||||
|
invitationDao.invite(alice, 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.'
|
||||||
|
});
|
||||||
|
|
||||||
|
invitationDao.invite(alice, bob, function(err, status) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
invitationDao.invite(alice, bob, function(err, status) {
|
||||||
|
expect(err).to.exist;
|
||||||
|
expect(status).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('check', function() {
|
||||||
|
it('should return pending invite', function(done) {
|
||||||
|
restDaoStub.get.yieldsAsync(null, undefined, 200);
|
||||||
|
|
||||||
|
invitationDao.check(alice, bob, function(err, status) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(status).to.equal(InvitationDAO.INVITE_PENDING);
|
||||||
|
expect(restDaoStub.get.calledWith(null, expectedUri)).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return missing invite', function(done) {
|
||||||
|
restDaoStub.get.yieldsAsync({
|
||||||
|
code: 404
|
||||||
|
});
|
||||||
|
|
||||||
|
invitationDao.check(alice, bob, function(err, status) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(status).to.equal(InvitationDAO.INVITE_MISSING);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not work for http error', function(done) {
|
||||||
|
restDaoStub.get.yieldsAsync({
|
||||||
|
code: 1337,
|
||||||
|
errMsg: 'jawollja.'
|
||||||
|
});
|
||||||
|
|
||||||
|
invitationDao.check(alice, bob, function(err, status) {
|
||||||
|
expect(err).to.exist;
|
||||||
|
expect(status).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not work for unexpected response', function(done) {
|
||||||
|
restDaoStub.get.yieldsAsync(null, undefined, 1337);
|
||||||
|
|
||||||
|
invitationDao.check(alice, bob, function(err, status) {
|
||||||
|
expect(err).to.exist;
|
||||||
|
expect(status).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -48,7 +48,8 @@ function startTests() {
|
|||||||
'test/new-unit/navigation-ctrl-test',
|
'test/new-unit/navigation-ctrl-test',
|
||||||
'test/new-unit/mail-list-ctrl-test',
|
'test/new-unit/mail-list-ctrl-test',
|
||||||
'test/new-unit/write-ctrl-test',
|
'test/new-unit/write-ctrl-test',
|
||||||
'test/new-unit/outbox-bo-test'
|
'test/new-unit/outbox-bo-test',
|
||||||
|
'test/new-unit/invitation-dao-test'
|
||||||
], function() {
|
], function() {
|
||||||
//Tests loaded, run tests
|
//Tests loaded, run tests
|
||||||
mocha.run();
|
mocha.run();
|
||||||
|
@ -10,14 +10,13 @@ define(function(require) {
|
|||||||
var restDao;
|
var restDao;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
sinon.stub($, 'ajax').yieldsTo('success', {
|
|
||||||
foo: 'bar'
|
|
||||||
});
|
|
||||||
restDao = new RestDAO();
|
restDao = new RestDAO();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
$.ajax.restore();
|
if (typeof $.ajax.callCount !== 'undefined') {
|
||||||
|
$.ajax.restore();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('contructor', function() {
|
describe('contructor', function() {
|
||||||
@ -40,73 +39,81 @@ define(function(require) {
|
|||||||
|
|
||||||
describe('get', function() {
|
describe('get', function() {
|
||||||
it('should work with json as default type', function(done) {
|
it('should work with json as default type', function(done) {
|
||||||
$.ajax.restore();
|
|
||||||
var spy = sinon.stub($, 'ajax').yieldsTo('success', {
|
var spy = sinon.stub($, 'ajax').yieldsTo('success', {
|
||||||
foo: 'bar'
|
foo: 'bar'
|
||||||
|
}, 'success', {
|
||||||
|
status: 200
|
||||||
});
|
});
|
||||||
|
|
||||||
restDao.get({
|
restDao.get({
|
||||||
uri: '/asdf',
|
uri: '/asdf',
|
||||||
type: 'json'
|
type: 'json'
|
||||||
}, function(err, data) {
|
}, function(err, data, status) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(data.foo).to.equal('bar');
|
expect(data.foo).to.equal('bar');
|
||||||
expect(spy.calledWith(sinon.match(function(request) {
|
expect(spy.calledWith(sinon.match(function(request) {
|
||||||
return request.headers.Accept === 'application/json' && request.dataType === 'json';
|
return request.headers.Accept === 'application/json' && request.dataType === 'json';
|
||||||
}))).to.be.true;
|
}))).to.be.true;
|
||||||
|
expect(status).to.equal(200);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with json', function(done) {
|
it('should work with json', function(done) {
|
||||||
$.ajax.restore();
|
|
||||||
var spy = sinon.stub($, 'ajax').yieldsTo('success', {
|
var spy = sinon.stub($, 'ajax').yieldsTo('success', {
|
||||||
foo: 'bar'
|
foo: 'bar'
|
||||||
|
}, 'success', {
|
||||||
|
status: 200
|
||||||
});
|
});
|
||||||
|
|
||||||
restDao.get({
|
restDao.get({
|
||||||
uri: '/asdf',
|
uri: '/asdf',
|
||||||
type: 'json'
|
type: 'json'
|
||||||
}, function(err, data) {
|
}, function(err, data, status) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(data.foo).to.equal('bar');
|
expect(data.foo).to.equal('bar');
|
||||||
expect(spy.calledWith(sinon.match(function(request) {
|
expect(spy.calledWith(sinon.match(function(request) {
|
||||||
return request.headers.Accept === 'application/json' && request.dataType === 'json';
|
return request.headers.Accept === 'application/json' && request.dataType === 'json';
|
||||||
}))).to.be.true;
|
}))).to.be.true;
|
||||||
|
expect(status).to.equal(200);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with plain text', function(done) {
|
it('should work with plain text', function(done) {
|
||||||
$.ajax.restore();
|
var spy = sinon.stub($, 'ajax').yieldsTo('success', 'foobar!', 'success', {
|
||||||
var spy = sinon.stub($, 'ajax').yieldsTo('success', 'foobar!');
|
status: 200
|
||||||
|
});
|
||||||
|
|
||||||
restDao.get({
|
restDao.get({
|
||||||
uri: '/asdf',
|
uri: '/asdf',
|
||||||
type: 'text'
|
type: 'text'
|
||||||
}, function(err, data) {
|
}, function(err, data, status) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(data).to.equal('foobar!');
|
expect(data).to.equal('foobar!');
|
||||||
expect(spy.calledWith(sinon.match(function(request) {
|
expect(spy.calledWith(sinon.match(function(request) {
|
||||||
return request.headers.Accept === 'text/plain' && request.dataType === 'text';
|
return request.headers.Accept === 'text/plain' && request.dataType === 'text';
|
||||||
}))).to.be.true;
|
}))).to.be.true;
|
||||||
|
expect(status).to.equal(200);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with xml', function(done) {
|
it('should work with xml', function(done) {
|
||||||
$.ajax.restore();
|
var spy = sinon.stub($, 'ajax').yieldsTo('success', '<foo>bar</foo>', 'success', {
|
||||||
var spy = sinon.stub($, 'ajax').yieldsTo('success', '<foo>bar</foo>');
|
status: 200
|
||||||
|
});
|
||||||
|
|
||||||
restDao.get({
|
restDao.get({
|
||||||
uri: '/asdf',
|
uri: '/asdf',
|
||||||
type: 'xml'
|
type: 'xml'
|
||||||
}, function(err, data) {
|
}, function(err, data, status) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(data).to.equal('<foo>bar</foo>'); // that's probably not right, but in the unit test, it is :)
|
expect(data).to.equal('<foo>bar</foo>'); // that's probably not right, but in the unit test, it is :)
|
||||||
expect(spy.calledWith(sinon.match(function(request) {
|
expect(spy.calledWith(sinon.match(function(request) {
|
||||||
return request.headers.Accept === 'application/xml' && request.dataType === 'xml';
|
return request.headers.Accept === 'application/xml' && request.dataType === 'xml';
|
||||||
}))).to.be.true;
|
}))).to.be.true;
|
||||||
|
expect(status).to.equal(200);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -133,7 +140,6 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fail for server error', function(done) {
|
it('should fail for server error', function(done) {
|
||||||
$.ajax.restore();
|
|
||||||
sinon.stub($, 'ajax').yieldsTo('error', {
|
sinon.stub($, 'ajax').yieldsTo('error', {
|
||||||
status: 500
|
status: 500
|
||||||
}, {
|
}, {
|
||||||
@ -153,7 +159,6 @@ define(function(require) {
|
|||||||
|
|
||||||
describe('put', function() {
|
describe('put', function() {
|
||||||
it('should fail', function(done) {
|
it('should fail', function(done) {
|
||||||
$.ajax.restore();
|
|
||||||
sinon.stub($, 'ajax').yieldsTo('error', {
|
sinon.stub($, 'ajax').yieldsTo('error', {
|
||||||
status: 500
|
status: 500
|
||||||
}, {
|
}, {
|
||||||
@ -168,8 +173,15 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function(done) {
|
it('should work', function(done) {
|
||||||
restDao.put('/asdf', {}, function(err) {
|
var spy = sinon.stub($, 'ajax').yieldsTo('success', undefined, 'success', {
|
||||||
|
status: 201
|
||||||
|
});
|
||||||
|
|
||||||
|
restDao.put('/asdf', {}, function(err, res, status) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
|
expect(res).to.not.exist;
|
||||||
|
expect(spy.callCount).to.equal(1);
|
||||||
|
expect(status).to.equal(201);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -177,7 +189,6 @@ define(function(require) {
|
|||||||
|
|
||||||
describe('remove', function() {
|
describe('remove', function() {
|
||||||
it('should fail', function(done) {
|
it('should fail', function(done) {
|
||||||
$.ajax.restore();
|
|
||||||
sinon.stub($, 'ajax').yieldsTo('error', {
|
sinon.stub($, 'ajax').yieldsTo('error', {
|
||||||
status: 500
|
status: 500
|
||||||
}, {
|
}, {
|
||||||
@ -192,8 +203,14 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function(done) {
|
it('should work', function(done) {
|
||||||
restDao.remove('/asdf', function(err) {
|
var spy = sinon.stub($, 'ajax').yieldsTo('success', undefined, 'success', {
|
||||||
|
status: 204
|
||||||
|
});
|
||||||
|
restDao.remove('/asdf', function(err, res, status) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
|
expect(res).to.not.exist;
|
||||||
|
expect(spy.callCount).to.equal(1);
|
||||||
|
expect(status).to.equal(204);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user