Skip to content

Commit

Permalink
Implemented getShoppingList
Browse files Browse the repository at this point in the history
Also modified accountRepository to remove a shopping list id from the
set of a user
  • Loading branch information
vgheri committed Jun 2, 2013
1 parent d085fb9 commit 8d8d1fe
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function setup(app, handlers) {
app.post('/api/lists/:id', handlers.list.createShoppingList);
app.put('/api/lists/:id', handlers.list.updateShoppingList);
//app.get('/api/lists/:userId', handlers.list.getShoppingLists);
//app.get('/api/profiles/:userId/lists/:shoppingListId', handlers.list.getShoppingList);
app.get('/api/profiles/:userId/lists/:shoppingListId', handlers.list.getShoppingList);
app.get('/api/profiles/:userId/lists', handlers.list.getShoppingLists);
app.del('/api/lists/:id', handlers.list.deleteShoppingList);
}
Expand Down
99 changes: 78 additions & 21 deletions handlers/ShoppingListHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ var logger = require('../utils/logger');
var ShoppingListHandler = function() {
this.createShoppingList = handleCreateShoppingListRequest;
this.getShoppingLists = handleGetShoppingListsRequest;
this.getShoppingList = handleGetShoppingListRequest;
this.updateShoppingList = handleUpdateShoppingListRequest;
this.deleteShoppingList = handleDeleteShoppingListRequest;
this.deleteShoppingList = handleDeleteShoppingListRequest;
};

// On success should return status code 201 to notify the client the account
Expand Down Expand Up @@ -113,19 +114,7 @@ function handleCreateShoppingListRequest(req, res) {
});
}
}
/*
function handleGetShoppingListsRequest(req, res) {
var userId = req.params.userId || null;
var query = req.query;
// If we have a query, it means we want to retrieve templates
if (query && query.isTemplate) {
handleGetTemplateListsForUserRequest(req, res, userId);
} //
else {
handleGetListsForUserRequest(req, res, userId);
}
}
*/

/// Retrieve the list of shopping lists (not templates) saved, created by the user, or shared with him.
/// If isTemplate is true, then retrieves the list of templates created by this user
/// Url: /api/profiles/:userId/lists
Expand All @@ -136,12 +125,80 @@ function handleGetShoppingListsRequest(req, res) {
// If we have a query, it means we want to retrieve templates
if (query && query.isTemplate) {
handleGetTemplateListsForUserRequest(req, res, userId);
} //
}
else {
handleGetListsForUserRequest(req, res, userId);
}
}

/// Retrieve a shopping list (also a template) for a certain user
/// Url: /api/profiles/:userId/lists/:shoppingListId
function handleGetShoppingListRequest(req, res) {
var userId = req.params.userId || null;
var shoppingListId = req.params.shoppingListId || null;
var accountRepository = new AccountRepository();
if (userId && shoppingListId) {
// 1: Retrieve the user object
accountRepository.findById(userId)
.then(function(account) {
if (account) {
// 2: If the user exists, check if the list id belongs to the list of shoppingLists for this user
if (account.shoppingLists.indexOf(shoppingListId) > -1 ) {
// If yes, retrieve the list by id and serve it to the client
var shoppingListRepository = new ShoppingListRepository();
return shoppingListRepository.findById(shoppingListId);
}
else {
// If no, return HTTP 404 not found
logger.log('info', 'Could not find shopping list ' + shoppingListId + ' for user ' + userId +
'. Request from address ' + req.connection.remoteAddress + '.');
res.json(404, {
error: "Not found"
});
}
}
else {
// 3: Else If the user doesn't exist -> 404
logger.log('info', 'Could not retrieve shopping list ' + shoppingListId +
', for user ' + userId + '. No such user id exists. Request from address ' + req.connection.remoteAddress + '.');
res.json(404, {
error: "No account found matching id " + userId
});
}
})
.then(function(shoppingList) {
if (shoppingList) {
logger.log('info', 'User ' + userId + ' retrieved shopping list ' + shoppingListId + '. ' +
'Request from address ' + req.connection.remoteAddress + '.');
res.json(200, shoppingList);
}
else {
// 3: Else If the user doesn't exist -> 404
logger.log('info', 'Could not retrieve shopping list ' + shoppingListId +
', for user ' + userId + '. No such user shopping list exists. Request from address ' + req.connection.remoteAddress + '.');
res.json(404, {
error: "No account found matching id " + userId
});
}
})
.fail(function(err) {
res.json(500, {
error: err.message
});
logger.lsog('error', 'An error has occurred while processing a request ' +
' to retrieve shopping list with id ' + shoppingListId + ' for user ' + userId + ' from ' +
req.connection.remoteAddress + '. Stack trace: ' + err.stack);
});
}
else {
// 400 BAD REQUEST
logger.log('info', 'Bad request from ' +
req.connection.remoteAddress + '. Message: ' + err.message);
res.json(400);
}
}

/// TODO: Check if the user has this shopping list id in the shoppingLists array and if the user is the creator of this list
function handleUpdateShoppingListRequest(req, res) {
// Retrieve the shopping list id from the request
var id = req.params.id || null;
Expand All @@ -165,25 +222,25 @@ function handleUpdateShoppingListRequest(req, res) {
},
function(err) {
if (err.isBadRequest) {
logger.log('info', 'Bad request from ' +
req.connection.remoteAddress + '. Message: ' + err.message);
res.json(400, {
error: err.message
});
winston.log('error', 'An error has occurred while processing a request ' +
' to update shopping list with id ' + id + ' from ' +
req.connection.remoteAddress + '. Message: ' + err.message);
}
else {
logger.log('error', 'An error has occurred while processing a request ' +
' to update shopping list with id ' + id + ' from ' +
req.connection.remoteAddress + '. Stack trace: ' + err.stack);
res.json(500, {
error: err.message
});
winston.log('error', 'An error has occurred while processing a request ' +
' to update shopping list with id ' + id + ' from ' +
req.connection.remoteAddress + '. Stack trace: ' + err.stack);
}
});
}
}

/// TODO: Check if the user has this shopping list id in the shoppingLists array and if the user is the creator of this list. If yes, then remove the id from the list
function handleDeleteShoppingListRequest(req, res) {
var listId = req.params.id || null;
var shoppingListRepository = new ShoppingListRepository();
Expand Down
25 changes: 25 additions & 0 deletions repositories/accountRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var Q = require('q');
function AccountRepository() {
this.findById = findAccountById;
this.addShoppingListToUser = addShoppingListToUser;
this.removeShoppingListFromUser = removeShoppingListFromUser;
this.createAccount = createAccount;
this.findAccountByUsername = findAccountByUsername;
this.updateAccount = updateAccount;
Expand Down Expand Up @@ -50,6 +51,30 @@ function addShoppingListToUser(profile, listId) {
return deferred.promise;
}

function removeShoppingListFromUser(profile, listId) {
var deferred = Q.defer();
if (profile.shoppingLists && profile.shoppingLists.length > 0) {
if (profile.shoppingLists.indexOf(listId) > -1) {
profile.shoppingLists.pull(listId);
profile.save(function(err, profile) {
if (err) {
deferred.reject(new Error(err));
}
else {
deferred.resolve(profile);
}
});
}
else {
deferred.reject(new Error('No such id'));
}
}
else {
deferred.reject(new Error('Shopping list is empty for this user'));
}
return deferred.promise;
}

function createAccount(username, password, firstName, lastName) {
var deferred = Q.defer();
var account = new Account({
Expand Down
59 changes: 53 additions & 6 deletions test/Routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@
throw err;
}
res.should.have.status(200);
res.body.should.have.property('_id');
res.body.creationDate.should.not.equal(null);
res.body.should.have.property('_id');
res.body.creationDate.should.not.equal(null);
done();
});
});
Expand Down Expand Up @@ -223,6 +223,22 @@
done();
});
});
it('should retrieve the just created list',
function(done) {
request(url)
.get('/api/profiles/' + userId + '/lists/' + shoppingListId)
.expect('Content-Type', /json/)
.end(function(err,res) {
if (err) {
throw err;
}
res.should.have.status(200);
res.body.should.have.property('_id');
res.body.creationDate.should.not.equal(null);
res.body.should.have.property('title', 'Test list');
done();
});
});
it('should have added the newly created list to the lists of the user vgheri',
function(done) {
request(url)
Expand All @@ -238,6 +254,32 @@
done();
});
});
it('should return 404 trying to retrieve a shopping list for a nonexistent user',
function(done) {
request(url)
.get('/api/profiles/5149d6d382d09b6722232772/lists/' + shoppingListId)
.expect('Content-Type', /json/)
.end(function(err,res) {
if (err) {
throw err;
}
res.should.have.status(404);
done();
});
});
it('should return 404 trying to retrieve a nonexistent shopping list for this user',
function(done) {
request(url)
.get('/api/profiles/' + userId + '/lists/5149d6d382d09b6722232772')
.expect('Content-Type', /json/)
.end(function(err,res) {
if (err) {
throw err;
}
res.should.have.status(404);
done();
});
});
it('should return error saving a shopping list without a title',
function(done) {
var emptyShoppingList = {
Expand Down Expand Up @@ -411,7 +453,8 @@
done();
});
});
it('should return a 404 status code trying to delete an unknown shopping list', function(done){
it('should return a 404 status code trying to delete an unknown shopping list',
function(done){
request(url)
.del('/api/lists/507f191e810c19729de860ea')
.expect(404)
Expand All @@ -422,7 +465,8 @@
done();
});
});
it('should correctly delete an existing shopping list and return 204', function(done){
it('should correctly delete an existing shopping list and return 204',
function(done){
request(url)
.del('/api/lists/' + shoppingListId)
.expect(204)
Expand All @@ -431,7 +475,10 @@
throw err;
}
done();
});/*
});
});
it('should reply with 404 trying to retrieve the just deleted shopping list',
function(done) {
request(url)
.get('/api/profiles/' + userId + '/lists/' + shoppingListId)
.expect(404)
Expand All @@ -440,7 +487,7 @@
throw err;
}
done();
});*/
});
});
});
});
Expand Down

0 comments on commit 8d8d1fe

Please sign in to comment.