accounts.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. var should = require('should'),
  2. request = require('supertest'),
  3. app = require('../server.js'),
  4. Db = require('./db.js'),
  5. globalServer, token, hacker_token, account_id;
  6. describe('API /accounts', function() {
  7. before( function(done) {
  8. globalServer = app.listen();
  9. token = Db.get_user_token();
  10. hacker_token = Db.get_hacker_token();
  11. account_id = Db.ACCOUNT_ID;
  12. Db.init(done);
  13. });
  14. after( function() {
  15. globalServer.close();
  16. });
  17. describe('* List', function() {
  18. it('should return the list of accounts', function(done) {
  19. request(globalServer)
  20. .get('/api/accounts')
  21. .set('Authorization', 'JWT ' + token)
  22. .set('Accept', 'application/json')
  23. .expect(200)
  24. .expect('Content-Type', /json/)
  25. .end( function(error, result) {
  26. should.not.exist(error);
  27. var accounts = result.body;
  28. should.exist(accounts);
  29. accounts.should.be.instanceof(Array).and.have.lengthOf(1);
  30. var account = accounts[0];
  31. account._id.should.be.equal(account_id);
  32. account.name.should.be.equal('Default');
  33. account.reference.should.be.equal('1234567890');
  34. done();
  35. });
  36. });
  37. it('should fail to list accounts without valid token', function(done) {
  38. request(globalServer)
  39. .get('/api/accounts')
  40. .set('Authorization', 'JWT fake')
  41. .expect(401, done);
  42. });
  43. it('should fail to list accounts without token', function(done) {
  44. request(globalServer)
  45. .get('/api/accounts')
  46. .expect(401, done);
  47. });
  48. });
  49. describe('* Creation', function() {
  50. it('should create an account', function(done) {
  51. request(globalServer)
  52. .post('/api/accounts')
  53. .send({
  54. name: 'Home',
  55. reference: '1234567890'
  56. })
  57. .set('Authorization', 'JWT ' + token)
  58. .set('Accept', 'application/json')
  59. .expect(201)
  60. .expect('Content-Type', /json/)
  61. .end( function(error, result) {
  62. should.not.exist(error);
  63. var account = result.body;
  64. should.exist(account);
  65. account.name.should.be.equal('Home');
  66. account.reference.should.be.equal('1234567890');
  67. done();
  68. });
  69. });
  70. it('should fail to create account without params', function(done) {
  71. request(globalServer)
  72. .post('/api/accounts')
  73. .set('Authorization', 'JWT ' + token)
  74. .set('Accept', 'application/json')
  75. .expect(400)
  76. .expect('Content-Type', /json/)
  77. .end( function(error, result) {
  78. var errors = result.body;
  79. should.exist(errors);
  80. errors.should.be.instanceof(Array).and.have.lengthOf(1);
  81. var error = errors[0];
  82. error.field.should.be.equal('name');
  83. done();
  84. });
  85. });
  86. it('should fail to create account without valid token', function(done) {
  87. request(globalServer)
  88. .post('/api/accounts')
  89. .send({
  90. name: 'Home',
  91. reference: '1234567890'
  92. })
  93. .set('Authorization', 'JWT fake')
  94. .expect(401, done);
  95. });
  96. it('should fail to create account without token', function(done) {
  97. request(globalServer)
  98. .post('/api/accounts')
  99. .send({
  100. name: 'Home',
  101. reference: '1234567890'
  102. })
  103. .expect(401, done);
  104. });
  105. });
  106. describe('* Deletion', function() {
  107. it('should delete the given account', function(done) {
  108. request(globalServer)
  109. .post('/api/accounts')
  110. .send({
  111. name: 'Todelete',
  112. reference: '0987654321'
  113. })
  114. .set('Authorization', 'JWT ' + token)
  115. .end(function(error, result) {
  116. var account_to_delete_id = result.body._id;
  117. request(globalServer)
  118. .delete('/api/accounts/' + account_to_delete_id)
  119. .set('Authorization', 'JWT ' + token)
  120. .set('Accept', 'application/json')
  121. .expect(204, done);
  122. });
  123. });
  124. it('should fail to delete unknown account', function(done) {
  125. request(globalServer)
  126. .delete('/api/accounts/4fc67871349bb7bf6a000002')
  127. .set('Authorization', 'JWT ' + token)
  128. .expect(404, done);
  129. });
  130. it('should fail to delete invalid account', function(done) {
  131. request(globalServer)
  132. .delete('/api/accounts/1')
  133. .set('Authorization', 'JWT ' + token)
  134. .expect(404, done);
  135. });
  136. it('should fail to delete account for another user', function(done) {
  137. request(globalServer)
  138. .post('/api/accounts')
  139. .send({
  140. name: 'Todelete',
  141. reference: '0987654321'
  142. })
  143. .set('Authorization', 'JWT ' + token)
  144. .end(function(error, result) {
  145. var account_to_delete_id = result.body._id;
  146. request(globalServer)
  147. .delete('/api/accounts/' + account_to_delete_id)
  148. .set('Authorization', 'JWT ' + hacker_token)
  149. .expect(401, done);
  150. });
  151. });
  152. });
  153. describe('* Retrieve', function() {
  154. it('should retrieve the given account', function(done) {
  155. request(globalServer)
  156. .get('/api/accounts/' + account_id)
  157. .set('Authorization', 'JWT ' + token)
  158. .expect(200)
  159. .expect('Content-Type', /json/)
  160. .end( function(error, result) {
  161. should.not.exist(error);
  162. var account = result.body;
  163. should.exist(account);
  164. account.name.should.be.equal('Default');
  165. account.reference.should.be.equal('1234567890');
  166. done();
  167. })
  168. });
  169. it('should fail to retrieve an unknown account', function(done) {
  170. request(globalServer)
  171. .get('/api/accounts/4fc67871349bb7bf6a000002')
  172. .set('Authorization', 'JWT ' + token)
  173. .expect(404, done);
  174. });
  175. it('should fail to retrieve an invalid account', function(done) {
  176. request(globalServer)
  177. .get('/api/accounts/1')
  178. .set('Authorization', 'JWT ' + token)
  179. .expect(404, done);
  180. });
  181. it('should fail to retrieve the account for another user', function(done) {
  182. request(globalServer)
  183. .get('/api/accounts/' + account_id)
  184. .set('Authorization', 'JWT ' + hacker_token)
  185. .expect(401, done);
  186. });
  187. });
  188. describe('* Modify', function() {
  189. it('should modify the given account', function(done) {
  190. request(globalServer)
  191. .put('/api/accounts/' + account_id)
  192. .send( {
  193. name: 'Home 2',
  194. reference: '0987654321'
  195. })
  196. .set('Authorization', 'JWT ' + token)
  197. .expect(200)
  198. .expect('Content-Type', /json/)
  199. .end(function(error, result) {
  200. should.not.exist(error);
  201. var account = result.body;
  202. should.exist(account);
  203. account.name.should.be.equal('Home 2');
  204. account.reference.should.be.equal('0987654321');
  205. done();
  206. });
  207. });
  208. it('should fail to modify without arguments', function(done) {
  209. request(globalServer)
  210. .put('/api/accounts/' + account_id)
  211. .set('Authorization', 'JWT ' + token)
  212. .expect(400, done)
  213. });
  214. it('should fail to modify missing arguments', function(done) {
  215. request(globalServer)
  216. .put('/api/accounts/' + account_id)
  217. .send({reference: 'AZERTY'})
  218. .set('Authorization', 'JWT ' + token)
  219. .expect(400, done);
  220. });
  221. it('should fail to modify invalid account', function(done) {
  222. request(globalServer)
  223. .put('/api/accounts/1')
  224. .set('Authorization', 'JWT ' + token)
  225. .expect(404, done)
  226. });
  227. it('should fail to modify account for another user', function(done) {
  228. request(globalServer)
  229. .put('/api/accounts/' + account_id)
  230. .set('Authorization', 'JWT ' + hacker_token)
  231. .expect(401, done)
  232. });
  233. });
  234. describe('* Entries', function() {
  235. describe('* Listing', function() {
  236. it('should list all entries', function(done) {
  237. request(globalServer)
  238. .get('/api/accounts/' + account_id + '/entries')
  239. .set('Authorization', 'JWT ' + token)
  240. .expect(200)
  241. .expect('Content-Type', /json/)
  242. .end(function(error, result) {
  243. should.not.exist(error);
  244. var entry = result.body.entry;
  245. should.not.exist(entry);
  246. var entries = result.body.entries;
  247. should.exist(entries);
  248. entries.should.be.instanceof(Array).and.have.lengthOf(1);
  249. new Date(entries[0].date).should.eql(new Date('2015-08-13'))
  250. entries[0].type.should.be.equal('BILL');
  251. entries[0].amount.should.be.equal(-100);
  252. should.exist(result.body.balance);
  253. done();
  254. });
  255. });
  256. it('should fail to list entries for unknown account', function(done) {
  257. request(globalServer)
  258. .get('/api/accounts/' + token + '/entries')
  259. .set('Authorization', 'JWT ' + token)
  260. .expect(404, done);
  261. });
  262. it('should fail to list entries for invalid account', function(done) {
  263. request(globalServer)
  264. .get('/api/accounts/1/entries')
  265. .set('Authorization', 'JWT ' + token)
  266. .expect(404, done);
  267. });
  268. it('should fail to list entries for not owned account', function(done) {
  269. request(globalServer)
  270. .get('/api/accounts/' + account_id + '/entries')
  271. .set('Authorization', 'JWT ' + hacker_token)
  272. .expect(401, done);
  273. });
  274. });
  275. describe('* Creation', function() {
  276. it('should create an entry with minimal data (DEPOSIT)' , function(done) {
  277. request(globalServer)
  278. .post('/api/accounts/' + account_id + '/entries')
  279. .send({
  280. amount: 1000,
  281. date: new Date('2015-08-14')
  282. })
  283. .set('Authorization', 'JWT ' + token)
  284. .expect(201)
  285. .expect('Content-Type', /json/)
  286. .end(function(error, result) {
  287. should.not.exist(error);
  288. var entry = result.body.entry;
  289. should.exist(entry);
  290. entry.amount.should.be.equal(1000);
  291. new Date(entry.date).should.eql(new Date(2015, 7, 14));
  292. entry.type.should.be.equal('DEPOSIT');
  293. should.not.exist(entry.category);
  294. should.not.exist(entry.sub_category);
  295. var entries = result.body.entries;
  296. should.exist(entries);
  297. entries.should.be.instanceof(Array).and.have.lengthOf(2);
  298. new Date(entries[0].date).should.eql(new Date('2015-08-14'))
  299. entries[0].type.should.be.equal('DEPOSIT');
  300. entries[0].amount.should.be.equal(1000);
  301. should.exist(result.body.balance);
  302. done();
  303. });
  304. });
  305. it('should create an entry with minimal data (BILL)' , function(done) {
  306. request(globalServer)
  307. .post('/api/accounts/' + account_id + '/entries')
  308. .send({
  309. label: 'test',
  310. amount: -1000,
  311. date: new Date('2015-08-15')
  312. })
  313. .set('Authorization', 'JWT ' + token)
  314. .expect(201)
  315. .expect('Content-Type', /json/)
  316. .end(function(error, result) {
  317. should.not.exist(error);
  318. var entry = result.body.entry;
  319. should.exist(entry);
  320. entry.amount.should.be.equal(-1000);
  321. new Date(entry.date).should.eql(new Date(2015, 7, 15));
  322. entry.type.should.be.equal('BILL');
  323. should.not.exist(entry.category);
  324. should.not.exist(entry.sub_category);
  325. var entries = result.body.entries;
  326. should.exist(entries);
  327. entries.should.be.instanceof(Array).and.have.lengthOf(3);
  328. new Date(entries[0].date).should.eql(new Date('2015-08-15'))
  329. entries[0].type.should.be.equal('BILL');
  330. entries[0].amount.should.be.equal(-1000);
  331. should.exist(result.body.balance);
  332. done();
  333. });
  334. });
  335. it('should fail to create entry without data', function(done) {
  336. request(globalServer)
  337. .post('/api/accounts/' + account_id + '/entries')
  338. .set('Authorization', 'JWT ' + token)
  339. .expect(400, done);
  340. });
  341. it('should fail to create entry for not owned account', function(done) {
  342. request(globalServer)
  343. .post('/api/accounts/' + account_id + '/entries')
  344. .set('Authorization', 'JWT ' + hacker_token)
  345. .send({
  346. label: 'test',
  347. amount: -1000,
  348. date: new Date('2014-12-08')
  349. })
  350. .expect(401, done);
  351. });
  352. it('should fail to create entry for not valid account', function(done) {
  353. request(globalServer)
  354. .post('/api/accounts/1/entries')
  355. .send({
  356. label: 'test',
  357. amount: -1000,
  358. date: new Date('2014-12-08')
  359. })
  360. .set('Authorization', 'JWT ' + token)
  361. .expect(404, done);
  362. });
  363. it('should fail to create entry for unknown account', function(done) {
  364. request(globalServer)
  365. .post('/api/accounts/' + token + '/entries')
  366. .send({
  367. label: 'test',
  368. amount: -1000,
  369. date: new Date('2014-12-08')
  370. })
  371. .set('Authorization', 'JWT ' + token)
  372. .expect(404, done);
  373. });
  374. });
  375. describe('* Modify', function() {
  376. it('should modify the given entry', function(done) {
  377. request(globalServer)
  378. .post('/api/accounts/' + account_id + '/entries')
  379. .send({
  380. label: 'test',
  381. amount: 50,
  382. date: new Date('2014-12-08')
  383. })
  384. .set('Authorization', 'JWT ' + token)
  385. .end(function(error, result) {
  386. var entry_id = result.body.entry._id;
  387. request(globalServer)
  388. .put('/api/accounts/' + account_id + '/entries/' + entry_id)
  389. .send({
  390. label: 'modified',
  391. amount: 55,
  392. date: new Date('2014-12-09')
  393. })
  394. .set('Authorization', 'JWT ' + token)
  395. .expect(200)
  396. .expect('Content-Type', /json/)
  397. .end( function(errors, result) {
  398. should.not.exist(errors);
  399. var entry = result.body.entry;
  400. should.exist(entry);
  401. entry.label.should.be.equal('modified');
  402. entry.amount.should.be.equal(55);
  403. new Date(entry.date).should.eql(new Date(2014,11,9));
  404. var entries = result.body.entries;
  405. should.exist(entries);
  406. entries.should.be.instanceof(Array);
  407. should.exist(result.body.balance);
  408. done();
  409. });
  410. });
  411. });
  412. it('should fail to modify the given entry without data', function(done) {
  413. request(globalServer)
  414. .post('/api/accounts/' + account_id + '/entries')
  415. .send({
  416. label: 'test',
  417. amount: 50,
  418. date: new Date('2014-12-08')
  419. })
  420. .set('Authorization', 'JWT ' + token)
  421. .end(function(error, result) {
  422. var entry_id = result.body.entry._id;
  423. request(globalServer)
  424. .put('/api/accounts/' + account_id + '/entries/' + entry_id)
  425. .set('Authorization', 'JWT ' + token)
  426. .expect(400, done);
  427. });
  428. });
  429. it('should fail to modify unknown entry', function(done) {
  430. request(globalServer)
  431. .post('/api/accounts/' + account_id + '/entries')
  432. .send({
  433. label: 'test',
  434. amount: 50,
  435. date: new Date('2014-12-08')
  436. })
  437. .set('Authorization', 'JWT ' + token)
  438. .end(function(error, result) {
  439. request(globalServer)
  440. .put('/api/accounts/' + account_id + '/entries/' + token)
  441. .send({
  442. label: 'modified',
  443. amount: 55,
  444. date: new Date('2014-12-09')
  445. })
  446. .set('Authorization', 'JWT ' + token)
  447. .expect(404, done);
  448. });
  449. });
  450. it('should fail to modify invalid entry', function(done) {
  451. request(globalServer)
  452. .post('/api/accounts/' + account_id + '/entries')
  453. .send({
  454. label: 'test',
  455. amount: 50,
  456. date: new Date('2014-12-08')
  457. })
  458. .set('Authorization', 'JWT ' + token)
  459. .end(function(error, result) {
  460. var entry_id = result.body._id;
  461. request(globalServer)
  462. .put('/api/accounts/' + account_id + '/entries/1')
  463. .send({
  464. label: 'modified',
  465. amount: 55,
  466. date: new Date('2014-12-09')
  467. })
  468. .set('Authorization', 'JWT ' + token)
  469. .expect(404, done);
  470. });
  471. });
  472. it('should fail to modify the given entry for unknown account', function(done) {
  473. request(globalServer)
  474. .post('/api/accounts/' + account_id + '/entries')
  475. .send({
  476. label: 'test',
  477. amount: 50,
  478. date: new Date('2014-12-08')
  479. })
  480. .set('Authorization', 'JWT ' + token)
  481. .end(function(error, result) {
  482. var entry_id = result.body._id;
  483. request(globalServer)
  484. .put('/api/accounts/' + token + '/entries/' + entry_id)
  485. .send({
  486. label: 'modified',
  487. amount: 55,
  488. date: new Date('2014-12-09')
  489. })
  490. .set('Authorization', 'JWT ' + token)
  491. .expect(404, done);
  492. });
  493. });
  494. it('should fail to modify the given entry for invalid account', function(done) {
  495. request(globalServer)
  496. .post('/api/accounts/' + account_id + '/entries')
  497. .send({
  498. label: 'test',
  499. amount: 50,
  500. date: new Date('2014-12-08')
  501. })
  502. .set('Authorization', 'JWT ' + token)
  503. .end(function(error, result) {
  504. var entry_id = result.body._id;
  505. request(globalServer)
  506. .put('/api/accounts/1/entries/' + entry_id)
  507. .send({
  508. label: 'modified',
  509. amount: 55,
  510. date: new Date('2014-12-09')
  511. })
  512. .set('Authorization', 'JWT ' + token)
  513. .expect(404, done);
  514. });
  515. });
  516. it('should fail to modify the given not owned entry', function(done) {
  517. request(globalServer)
  518. .post('/api/accounts/' + account_id + '/entries')
  519. .send({
  520. label: 'test',
  521. amount: 50,
  522. date: new Date('2014-12-08')
  523. })
  524. .set('Authorization', 'JWT ' + token)
  525. .end(function(error, result) {
  526. var entry_id = result.body._id;
  527. request(globalServer)
  528. .put('/api/accounts/' + account_id + '/entries/' + entry_id)
  529. .send({
  530. label: 'modified',
  531. amount: 55,
  532. date: new Date('2014-12-09')
  533. })
  534. .set('Authorization', 'JWT ' + hacker_token)
  535. .expect(401, done);
  536. });
  537. });
  538. });
  539. describe('* Deletion', function() {
  540. it('should delete the given entry', function(done) {
  541. request(globalServer)
  542. .post('/api/accounts/' + account_id + '/entries')
  543. .send({
  544. label: 'test',
  545. amount: 50,
  546. date: new Date('2014-12-08')
  547. })
  548. .set('Authorization', 'JWT ' + token)
  549. .end(function(error, result) {
  550. var entry_id = result.body.entry._id;
  551. request(globalServer)
  552. .delete('/api/accounts/' + account_id + '/entries/' + entry_id)
  553. .set('Authorization', 'JWT ' + token)
  554. .expect(200)
  555. .end(function(error, result) {
  556. should.exist(result.body.balance);
  557. done();
  558. });
  559. });
  560. });
  561. it('should fail to delete an unknown entry', function(done) {
  562. request(globalServer)
  563. .delete('/api/accounts/' + account_id + '/entries/' + token)
  564. .set('Authorization', 'JWT ' + token)
  565. .expect(404, done);
  566. });
  567. it('should fail to delete an invalid entry', function(done) {
  568. request(globalServer)
  569. .delete('/api/accounts/' + account_id + '/entries/1')
  570. .set('Authorization', 'JWT ' + token)
  571. .expect(404, done);
  572. });
  573. it('should fail to delete the not owned given entry', function(done) {
  574. request(globalServer)
  575. .post('/api/accounts/' + account_id + '/entries')
  576. .send({
  577. label: 'test',
  578. amount: 50,
  579. date: new Date('2014-12-08')
  580. })
  581. .set('Authorization', 'JWT ' + token)
  582. .end(function(error, result) {
  583. var entry_id = result.body.entry._id;
  584. request(globalServer)
  585. .delete('/api/accounts/' + account_id + '/entries/' + entry_id)
  586. .set('Authorization', 'JWT ' + hacker_token)
  587. .expect(401, done);
  588. });
  589. });
  590. });
  591. describe('* Retrieve', function() {
  592. it('should retrieve all entries', function(done) {
  593. request(globalServer)
  594. .get('/api/accounts/' + account_id + '/entries')
  595. .set('Authorization', 'JWT ' + token)
  596. .expect('Content-Type', /json/)
  597. .expect(200)
  598. .end(function(errors, result) {
  599. should.not.exist(errors);
  600. var entries = result.body.entries;
  601. should.exist(entries);
  602. entries.should.be.instanceof(Array);
  603. var balance = result.body.balance;
  604. should.exist(balance);
  605. balance.should.be.instanceof(Number);
  606. done();
  607. });
  608. });
  609. it('should fail to retrieve entries for unknown account', function(done) {
  610. request(globalServer)
  611. .get('/api/accounts/' + token + '/entries')
  612. .set('Authorization', 'JWT ' + token)
  613. .expect(404, done);
  614. });
  615. it('should fail to retrieve entries for invalid account', function(done) {
  616. request(globalServer)
  617. .get('/api/accounts/1/entries')
  618. .set('Authorization', 'JWT ' + token)
  619. .expect(404, done);
  620. });
  621. it('should fail to retrieve entries for the not owned given account', function(done) {
  622. request(globalServer)
  623. .get('/api/accounts/' + account_id + '/entries')
  624. .set('Authorization', 'JWT ' + hacker_token)
  625. .expect(401, done);
  626. });
  627. });
  628. });
  629. });