diff --git a/app/controllers/accounts.js b/app/controllers/accounts.js index bedfe1e..5beb58b 100644 --- a/app/controllers/accounts.js +++ b/app/controllers/accounts.js @@ -79,8 +79,8 @@ var list_entries = function(account_id, entry, callback ) { } Entry - .find({account_id: account_id}) - .sort({date: -1}) + .find({account_id: account_id}, {created_at: 0, __v: 0}) + .sort({date: -1,}) .exec(function(errors, entries) { if( errors ) { return callback(errors); @@ -88,7 +88,7 @@ var list_entries = function(account_id, entry, callback ) { return callback( null, { entry: entry, entries: entries, - balance: data[0].balance + balance: data ? data[0].balance : 0 }); }); }); @@ -175,7 +175,7 @@ module.exports = { sub_category: data.sub_category ? new ObjectId(data.sub_category) : undefined, label: data.label, amount: data.amount, - date: new Date(data.date), + date: data.date, type: data.amount >= 0 ? 'DEPOSIT' : 'BILL' }); diff --git a/app/routes/accounts.js b/app/routes/accounts.js index ad8ddf4..6c5058d 100644 --- a/app/routes/accounts.js +++ b/app/routes/accounts.js @@ -294,6 +294,48 @@ module.exports = function(app) { */ app.put('/api/accounts/:account_id', passport.jwt, AccountController.modify); + /** + * @api {get} /accounts/:account_id/entries List account entries + * @apiVersion 1.0.0 + * @apiName List entries + * @apiGroup Entries + * + * @apiParam {String} account_id The account id to retrieve + * + * @apiHeader {String} Content-Type application/json + * + * @apiHeader {String} Authorization The valid JWT token provided by the {post} /users/login resource + * @apiHeaderExample {string} Authorization header example: + * "Authorization": "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTVlNmU0ZTAwNTIzMGY0OTI3MWM3MDc4IiwiaWF0IjoxNDQxMTk1MjMyfQ.eWh9nuXVVSVDKKCmTMDoc9FBU55-KgkiOJH1hrdQRTQ" + * @apiError (401) {json} AuthenticationFailed The user can't be found. + * @apiErrorExample AuthenticationFailed: + * HTTP/1.1 401 Not Found + * { + * "message": "Authentication failed" + * } + * + * @apiSuccess (200) {json} entries List of all account entries. + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * [ + * { + * _id: '', + * account_id: '1000', + * type: 'DEPOSIT' + * amount: 1000, + * date: 2015-09-03T10:04:11.481Z + * } + * ] + * + * @apiError (404) {json} AccountNotFound The account can't be found. + * @apiErrorExample AccountNotFound: + * HTTP/1.1 404 Not Found + * { + * "message": "Unknown account" + * } + */ + app.get('/api/accounts/:account_id/entries', passport.jwt, AccountController.list_entries); + /** * @api {post} /accounts/:account_id/entries Create entry * @apiVersion 1.0.0 diff --git a/public/api_data.js b/public/api_data.js index 9dc433d..56dfdc8 100644 --- a/public/api_data.js +++ b/public/api_data.js @@ -829,6 +829,110 @@ define({ "api": [ "filename": "app/routes/accounts.js", "groupTitle": "Entries" }, + { + "type": "get", + "url": "/accounts/:account_id/entries", + "title": "List account entries", + "version": "1.0.0", + "name": "List_entries", + "group": "Entries", + "parameter": { + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "

String

", + "optional": false, + "field": "account_id", + "description": "

The account id to retrieve

" + } + ] + } + }, + "header": { + "fields": { + "Header": [ + { + "group": "Header", + "type": "String", + "optional": false, + "field": "Content-Type", + "description": "

application/json

" + }, + { + "group": "Header", + "type": "String", + "optional": false, + "field": "Authorization", + "description": "

The valid JWT token provided by the {post} /users/login resource

" + } + ] + }, + "examples": [ + { + "title": "Authorization header example:", + "content": "\"Authorization\": \"JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTVlNmU0ZTAwNTIzMGY0OTI3MWM3MDc4IiwiaWF0IjoxNDQxMTk1MjMyfQ.eWh9nuXVVSVDKKCmTMDoc9FBU55-KgkiOJH1hrdQRTQ\"", + "type": "string" + } + ] + }, + "error": { + "fields": { + "401": [ + { + "group": "401", + "type": "

json

", + "optional": false, + "field": "AuthenticationFailed", + "description": "

The user can't be found.

" + } + ], + "404": [ + { + "group": "404", + "type": "

json

", + "optional": false, + "field": "AccountNotFound", + "description": "

The account can't be found.

" + } + ] + }, + "examples": [ + { + "title": "AuthenticationFailed:", + "content": "HTTP/1.1 401 Not Found\n{\n \"message\": \"Authentication failed\"\n}", + "type": "json" + }, + { + "title": "AccountNotFound:", + "content": "HTTP/1.1 404 Not Found\n {\n \"message\": \"Unknown account\"\n }", + "type": "json" + } + ] + }, + "success": { + "fields": { + "200": [ + { + "group": "200", + "type": "

json

", + "optional": false, + "field": "entries", + "description": "

List of all account entries.

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "HTTP/1.1 200 OK\n [\n {\n _id: '',\n account_id: '1000',\n type: 'DEPOSIT'\n amount: 1000,\n date: 2015-09-03T10:04:11.481Z\n }\n ]", + "type": "json" + } + ] + }, + "filename": "app/routes/accounts.js", + "groupTitle": "Entries" + }, { "type": "post", "url": "/accounts/:account_id/entries/:entry_id", diff --git a/public/api_data.json b/public/api_data.json index 8e0227b..679d9b2 100644 --- a/public/api_data.json +++ b/public/api_data.json @@ -829,6 +829,110 @@ "filename": "app/routes/accounts.js", "groupTitle": "Entries" }, + { + "type": "get", + "url": "/accounts/:account_id/entries", + "title": "List account entries", + "version": "1.0.0", + "name": "List_entries", + "group": "Entries", + "parameter": { + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "

String

", + "optional": false, + "field": "account_id", + "description": "

The account id to retrieve

" + } + ] + } + }, + "header": { + "fields": { + "Header": [ + { + "group": "Header", + "type": "String", + "optional": false, + "field": "Content-Type", + "description": "

application/json

" + }, + { + "group": "Header", + "type": "String", + "optional": false, + "field": "Authorization", + "description": "

The valid JWT token provided by the {post} /users/login resource

" + } + ] + }, + "examples": [ + { + "title": "Authorization header example:", + "content": "\"Authorization\": \"JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTVlNmU0ZTAwNTIzMGY0OTI3MWM3MDc4IiwiaWF0IjoxNDQxMTk1MjMyfQ.eWh9nuXVVSVDKKCmTMDoc9FBU55-KgkiOJH1hrdQRTQ\"", + "type": "string" + } + ] + }, + "error": { + "fields": { + "401": [ + { + "group": "401", + "type": "

json

", + "optional": false, + "field": "AuthenticationFailed", + "description": "

The user can't be found.

" + } + ], + "404": [ + { + "group": "404", + "type": "

json

", + "optional": false, + "field": "AccountNotFound", + "description": "

The account can't be found.

" + } + ] + }, + "examples": [ + { + "title": "AuthenticationFailed:", + "content": "HTTP/1.1 401 Not Found\n{\n \"message\": \"Authentication failed\"\n}", + "type": "json" + }, + { + "title": "AccountNotFound:", + "content": "HTTP/1.1 404 Not Found\n {\n \"message\": \"Unknown account\"\n }", + "type": "json" + } + ] + }, + "success": { + "fields": { + "200": [ + { + "group": "200", + "type": "

json

", + "optional": false, + "field": "entries", + "description": "

List of all account entries.

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "HTTP/1.1 200 OK\n [\n {\n _id: '',\n account_id: '1000',\n type: 'DEPOSIT'\n amount: 1000,\n date: 2015-09-03T10:04:11.481Z\n }\n ]", + "type": "json" + } + ] + }, + "filename": "app/routes/accounts.js", + "groupTitle": "Entries" + }, { "type": "post", "url": "/accounts/:account_id/entries/:entry_id", diff --git a/public/api_project.js b/public/api_project.js index aa23684..e1b1c74 100644 --- a/public/api_project.js +++ b/public/api_project.js @@ -8,7 +8,7 @@ define({ "apidoc": "0.2.0", "generator": { "name": "apidoc", - "time": "2015-09-29T13:08:53.151Z", + "time": "2015-10-05T12:34:33.802Z", "url": "http://apidocjs.com", "version": "0.13.1" } diff --git a/public/api_project.json b/public/api_project.json index 3fe206e..537ecfc 100644 --- a/public/api_project.json +++ b/public/api_project.json @@ -8,7 +8,7 @@ "apidoc": "0.2.0", "generator": { "name": "apidoc", - "time": "2015-09-29T13:08:53.151Z", + "time": "2015-10-05T12:34:33.802Z", "url": "http://apidocjs.com", "version": "0.13.1" } diff --git a/test/accounts.js b/test/accounts.js index 169bd19..a86bc6b 100644 --- a/test/accounts.js +++ b/test/accounts.js @@ -260,7 +260,55 @@ describe('API /accounts', function() { }); describe('* Entries', function() { - describe('* Creation', function() { + describe('* Listing', function() { + it('should list all entries', function(done) { + request(globalServer) + .get('/api/accounts/' + account_id + '/entries') + .set('Authorization', 'JWT ' + token) + .expect(200) + .expect('Content-Type', /json/) + .end(function(error, result) { + should.not.exist(error); + + var entry = result.body.entry; + should.not.exist(entry); + + var entries = result.body.entries; + should.exist(entries); + entries.should.be.instanceof(Array).and.have.lengthOf(1); + new Date(entries[0].date).should.eql(new Date('2015-08-13')) + entries[0].type.should.be.equal('BILL'); + entries[0].amount.should.be.equal(-100); + + should.exist(result.body.balance); + + done(); + }); + }); + + it('should fail to list entries for unknown account', function(done) { + request(globalServer) + .get('/api/accounts/' + token + '/entries') + .set('Authorization', 'JWT ' + token) + .expect(404, done); + }); + + it('should fail to list entries for invalid account', function(done) { + request(globalServer) + .get('/api/accounts/1/entries') + .set('Authorization', 'JWT ' + token) + .expect(404, done); + }); + + it('should fail to list entries for not owned account', function(done) { + request(globalServer) + .get('/api/accounts/' + account_id + '/entries') + .set('Authorization', 'JWT ' + hacker_token) + .expect(401, done); + }); + }); + + describe('* Creation', function() { it('should create an entry with minimal data (DEPOSIT)' , function(done) { request(globalServer) .post('/api/accounts/' + account_id + '/entries')