accounts.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  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('* Creation', function() {
  236. it('should create an entry with minimal data (DEPOSIT)' , function(done) {
  237. request(globalServer)
  238. .post('/api/accounts/' + account_id + '/entries')
  239. .send({
  240. amount: 1000,
  241. date: new Date('2015-08-14')
  242. })
  243. .set('Authorization', 'JWT ' + token)
  244. .expect(201)
  245. .expect('Content-Type', /json/)
  246. .end(function(error, result) {
  247. should.not.exist(error);
  248. var entry = result.body.entry;
  249. should.exist(entry);
  250. entry.amount.should.be.equal(1000);
  251. new Date(entry.date).should.eql(new Date(2015, 7, 14));
  252. entry.type.should.be.equal('DEPOSIT');
  253. should.not.exist(entry.category);
  254. should.not.exist(entry.sub_category);
  255. var entries = result.body.entries;
  256. should.exist(entries);
  257. entries.should.be.instanceof(Array).and.have.lengthOf(2);
  258. new Date(entries[0].date).should.eql(new Date('2015-08-14'))
  259. entries[0].type.should.be.equal('DEPOSIT');
  260. entries[0].amount.should.be.equal(1000);
  261. should.exist(result.body.balance);
  262. done();
  263. });
  264. });
  265. it('should create an entry with minimal data (BILL)' , function(done) {
  266. request(globalServer)
  267. .post('/api/accounts/' + account_id + '/entries')
  268. .send({
  269. label: 'test',
  270. amount: -1000,
  271. date: new Date('2015-08-15')
  272. })
  273. .set('Authorization', 'JWT ' + token)
  274. .expect(201)
  275. .expect('Content-Type', /json/)
  276. .end(function(error, result) {
  277. should.not.exist(error);
  278. var entry = result.body.entry;
  279. should.exist(entry);
  280. entry.amount.should.be.equal(-1000);
  281. new Date(entry.date).should.eql(new Date(2015, 7, 15));
  282. entry.type.should.be.equal('BILL');
  283. should.not.exist(entry.category);
  284. should.not.exist(entry.sub_category);
  285. var entries = result.body.entries;
  286. should.exist(entries);
  287. entries.should.be.instanceof(Array).and.have.lengthOf(3);
  288. new Date(entries[0].date).should.eql(new Date('2015-08-15'))
  289. entries[0].type.should.be.equal('BILL');
  290. entries[0].amount.should.be.equal(-1000);
  291. should.exist(result.body.balance);
  292. done();
  293. });
  294. });
  295. it('should fail to create entry without data', function(done) {
  296. request(globalServer)
  297. .post('/api/accounts/' + account_id + '/entries')
  298. .set('Authorization', 'JWT ' + token)
  299. .expect(400, done);
  300. });
  301. it('should fail to create entry for not owned account', function(done) {
  302. request(globalServer)
  303. .post('/api/accounts/' + account_id + '/entries')
  304. .set('Authorization', 'JWT ' + hacker_token)
  305. .send({
  306. label: 'test',
  307. amount: -1000,
  308. date: new Date('2014-12-08')
  309. })
  310. .expect(401, done);
  311. });
  312. it('should fail to create entry for not valid account', function(done) {
  313. request(globalServer)
  314. .post('/api/accounts/1/entries')
  315. .send({
  316. label: 'test',
  317. amount: -1000,
  318. date: new Date('2014-12-08')
  319. })
  320. .set('Authorization', 'JWT ' + token)
  321. .expect(404, done);
  322. });
  323. it('should fail to create entry for unknown account', function(done) {
  324. request(globalServer)
  325. .post('/api/accounts/' + token + '/entries')
  326. .send({
  327. label: 'test',
  328. amount: -1000,
  329. date: new Date('2014-12-08')
  330. })
  331. .set('Authorization', 'JWT ' + token)
  332. .expect(404, done);
  333. });
  334. });
  335. describe('* Modify', function() {
  336. it('should modify the given entry', function(done) {
  337. request(globalServer)
  338. .post('/api/accounts/' + account_id + '/entries')
  339. .send({
  340. label: 'test',
  341. amount: 50,
  342. date: new Date('2014-12-08')
  343. })
  344. .set('Authorization', 'JWT ' + token)
  345. .end(function(error, result) {
  346. var entry_id = result.body.entry._id;
  347. request(globalServer)
  348. .put('/api/accounts/' + account_id + '/entries/' + entry_id)
  349. .send({
  350. label: 'modified',
  351. amount: 55,
  352. date: new Date('2014-12-09')
  353. })
  354. .set('Authorization', 'JWT ' + token)
  355. .expect(200)
  356. .expect('Content-Type', /json/)
  357. .end( function(errors, result) {
  358. should.not.exist(errors);
  359. var entry = result.body.entry;
  360. should.exist(entry);
  361. entry.label.should.be.equal('modified');
  362. entry.amount.should.be.equal(55);
  363. new Date(entry.date).should.eql(new Date(2014,11,9));
  364. var entries = result.body.entries;
  365. should.exist(entries);
  366. entries.should.be.instanceof(Array);
  367. should.exist(result.body.balance);
  368. done();
  369. });
  370. });
  371. });
  372. it('should fail to modify the given entry without data', function(done) {
  373. request(globalServer)
  374. .post('/api/accounts/' + account_id + '/entries')
  375. .send({
  376. label: 'test',
  377. amount: 50,
  378. date: new Date('2014-12-08')
  379. })
  380. .set('Authorization', 'JWT ' + token)
  381. .end(function(error, result) {
  382. var entry_id = result.body.entry._id;
  383. request(globalServer)
  384. .put('/api/accounts/' + account_id + '/entries/' + entry_id)
  385. .set('Authorization', 'JWT ' + token)
  386. .expect(400, done);
  387. });
  388. });
  389. it('should fail to modify unknown entry', function(done) {
  390. request(globalServer)
  391. .post('/api/accounts/' + account_id + '/entries')
  392. .send({
  393. label: 'test',
  394. amount: 50,
  395. date: new Date('2014-12-08')
  396. })
  397. .set('Authorization', 'JWT ' + token)
  398. .end(function(error, result) {
  399. request(globalServer)
  400. .put('/api/accounts/' + account_id + '/entries/' + token)
  401. .send({
  402. label: 'modified',
  403. amount: 55,
  404. date: new Date('2014-12-09')
  405. })
  406. .set('Authorization', 'JWT ' + token)
  407. .expect(404, done);
  408. });
  409. });
  410. it('should fail to modify invalid entry', function(done) {
  411. request(globalServer)
  412. .post('/api/accounts/' + account_id + '/entries')
  413. .send({
  414. label: 'test',
  415. amount: 50,
  416. date: new Date('2014-12-08')
  417. })
  418. .set('Authorization', 'JWT ' + token)
  419. .end(function(error, result) {
  420. var entry_id = result.body._id;
  421. request(globalServer)
  422. .put('/api/accounts/' + account_id + '/entries/1')
  423. .send({
  424. label: 'modified',
  425. amount: 55,
  426. date: new Date('2014-12-09')
  427. })
  428. .set('Authorization', 'JWT ' + token)
  429. .expect(404, done);
  430. });
  431. });
  432. it('should fail to modify the given entry for unknown account', function(done) {
  433. request(globalServer)
  434. .post('/api/accounts/' + account_id + '/entries')
  435. .send({
  436. label: 'test',
  437. amount: 50,
  438. date: new Date('2014-12-08')
  439. })
  440. .set('Authorization', 'JWT ' + token)
  441. .end(function(error, result) {
  442. var entry_id = result.body._id;
  443. request(globalServer)
  444. .put('/api/accounts/' + token + '/entries/' + entry_id)
  445. .send({
  446. label: 'modified',
  447. amount: 55,
  448. date: new Date('2014-12-09')
  449. })
  450. .set('Authorization', 'JWT ' + token)
  451. .expect(404, done);
  452. });
  453. });
  454. it('should fail to modify the given entry for invalid account', function(done) {
  455. request(globalServer)
  456. .post('/api/accounts/' + account_id + '/entries')
  457. .send({
  458. label: 'test',
  459. amount: 50,
  460. date: new Date('2014-12-08')
  461. })
  462. .set('Authorization', 'JWT ' + token)
  463. .end(function(error, result) {
  464. var entry_id = result.body._id;
  465. request(globalServer)
  466. .put('/api/accounts/1/entries/' + entry_id)
  467. .send({
  468. label: 'modified',
  469. amount: 55,
  470. date: new Date('2014-12-09')
  471. })
  472. .set('Authorization', 'JWT ' + token)
  473. .expect(404, done);
  474. });
  475. });
  476. it('should fail to modify the given not owned entry', function(done) {
  477. request(globalServer)
  478. .post('/api/accounts/' + account_id + '/entries')
  479. .send({
  480. label: 'test',
  481. amount: 50,
  482. date: new Date('2014-12-08')
  483. })
  484. .set('Authorization', 'JWT ' + token)
  485. .end(function(error, result) {
  486. var entry_id = result.body._id;
  487. request(globalServer)
  488. .put('/api/accounts/' + account_id + '/entries/' + entry_id)
  489. .send({
  490. label: 'modified',
  491. amount: 55,
  492. date: new Date('2014-12-09')
  493. })
  494. .set('Authorization', 'JWT ' + hacker_token)
  495. .expect(401, done);
  496. });
  497. });
  498. });
  499. describe('* Deletion', function() {
  500. it('should delete the given entry', function(done) {
  501. request(globalServer)
  502. .post('/api/accounts/' + account_id + '/entries')
  503. .send({
  504. label: 'test',
  505. amount: 50,
  506. date: new Date('2014-12-08')
  507. })
  508. .set('Authorization', 'JWT ' + token)
  509. .end(function(error, result) {
  510. var entry_id = result.body.entry._id;
  511. request(globalServer)
  512. .delete('/api/accounts/' + account_id + '/entries/' + entry_id)
  513. .set('Authorization', 'JWT ' + token)
  514. .expect(200)
  515. .end(function(error, result) {
  516. should.exist(result.body.balance);
  517. done();
  518. });
  519. });
  520. });
  521. it('should fail to delete an unknown entry', function(done) {
  522. request(globalServer)
  523. .delete('/api/accounts/' + account_id + '/entries/' + token)
  524. .set('Authorization', 'JWT ' + token)
  525. .expect(404, done);
  526. });
  527. it('should fail to delete an invalid entry', function(done) {
  528. request(globalServer)
  529. .delete('/api/accounts/' + account_id + '/entries/1')
  530. .set('Authorization', 'JWT ' + token)
  531. .expect(404, done);
  532. });
  533. it('should fail to delete the not owned given entry', function(done) {
  534. request(globalServer)
  535. .post('/api/accounts/' + account_id + '/entries')
  536. .send({
  537. label: 'test',
  538. amount: 50,
  539. date: new Date('2014-12-08')
  540. })
  541. .set('Authorization', 'JWT ' + token)
  542. .end(function(error, result) {
  543. var entry_id = result.body.entry._id;
  544. request(globalServer)
  545. .delete('/api/accounts/' + account_id + '/entries/' + entry_id)
  546. .set('Authorization', 'JWT ' + hacker_token)
  547. .expect(401, done);
  548. });
  549. });
  550. });
  551. describe('* Retrieve', function() {
  552. it('should retrieve all entries', function(done) {
  553. request(globalServer)
  554. .get('/api/accounts/' + account_id + '/entries')
  555. .set('Authorization', 'JWT ' + token)
  556. .expect('Content-Type', /json/)
  557. .expect(200)
  558. .end(function(errors, result) {
  559. should.not.exist(errors);
  560. var entries = result.body.entries;
  561. should.exist(entries);
  562. entries.should.be.instanceof(Array);
  563. var balance = result.body.balance;
  564. should.exist(balance);
  565. balance.should.be.instanceof(Number);
  566. done();
  567. });
  568. });
  569. it('should fail to retrieve entries for unknown account', function(done) {
  570. request(globalServer)
  571. .get('/api/accounts/' + token + '/entries')
  572. .set('Authorization', 'JWT ' + token)
  573. .expect(404, done);
  574. });
  575. it('should fail to retrieve entries for invalid account', function(done) {
  576. request(globalServer)
  577. .get('/api/accounts/1/entries')
  578. .set('Authorization', 'JWT ' + token)
  579. .expect(404, done);
  580. });
  581. it('should fail to retrieve entries for the not owned given account', function(done) {
  582. request(globalServer)
  583. .get('/api/accounts/' + account_id + '/entries')
  584. .set('Authorization', 'JWT ' + hacker_token)
  585. .expect(401, done);
  586. });
  587. });
  588. });
  589. });