From a5b11105e5b878f113e5966775ba25a5b5ec73e3 Mon Sep 17 00:00:00 2001 From: Pierrick Date: Mon, 6 Jun 2016 14:13:15 +0200 Subject: [PATCH 1/6] Download statement Issue #7 --- lib/account.js | 31 ++++++++++++++++ lib/api.js | 11 ++++++ tests/account/statement.js | 68 +++++++++++++++++++++++++++++++++++ tests/fixtures/statement.pdf | Bin 0 -> 687 bytes tests/index.js | 1 + tests/unmock.js | 26 ++++++++++++-- 6 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 tests/account/statement.js create mode 100644 tests/fixtures/statement.pdf diff --git a/lib/account.js b/lib/account.js index d3a6324..64cf7f3 100644 --- a/lib/account.js +++ b/lib/account.js @@ -221,6 +221,14 @@ const utils = require('./utils'); * @property {Boolean} success */ +/** + * @typedef statement + * + * @property {String} id + * @property {String} type `pdf` for pdf buffer or `base64` for pdf in base64 + * @property {Buffer|String} pdf PDF encoded + */ + /** * @typedef statements * @@ -347,6 +355,29 @@ class Account { .then((meta) => utils.callApi(this, 'createOrUpdateMemo', {smartLinkId, meta, memo})); } + /** + * Get statement + * + * @description Return pdf buffer or base64 encoded + * + * @return {Promise} + */ + statement(id, pdf) { + pdf = !!pdf; + if (!id) { + return Promise.reject('MISSING_PARAMS'); + } + + return utils.callApi(this, 'getStatement', {id, pdf}) + .then(result => { + return { + id, + type: (pdf) ? 'pdf' : 'base64', + pdf: (pdf) ? new Buffer(result, 'binary') : result.pdf + }; + }); + } + /** * Get statements * diff --git a/lib/api.js b/lib/api.js index 2a0b31d..61e1137 100644 --- a/lib/api.js +++ b/lib/api.js @@ -142,6 +142,17 @@ module.exports = { .catch(errorHandler); }, + getStatement(token, options) { + return request.get({ + url: `${api}/api/statements/${(options.pdf) ? '' : 'json/'}${options.id}`, + json: !options.pdf, + headers: { + Authorization: `Bearer ${token}` + } + }) + .catch(errorHandler); + }, + getStatements(token) { return request.get({ url: `${api}/api/statements`, diff --git a/tests/account/statement.js b/tests/account/statement.js new file mode 100644 index 0000000..70020cc --- /dev/null +++ b/tests/account/statement.js @@ -0,0 +1,68 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const fs = require('fs'); +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('statement', () => { + it('should return a base64 statement', () => { + const apiStatements = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/statements/json/statement-2016-05') + .reply(200, { + id: 'statement-2016-05', + pdf: fs.readFileSync(`${__dirname}/../fixtures/statement.pdf`).toString('base64') + }); + + return n26.statement('statement-2016-05').then((statement) => { + expect(statement).to.have.property('id', 'statement-2016-05'); + expect(statement).to.have.property('type', 'base64'); + expect(statement).to.have.property('pdf').and.to.be.a('String'); + + expect(apiStatements.isDone()).to.be.true(); + }); + }); + + it('should return a buffer statement', () => { + const apiStatements = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/pdf' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/statements/statement-2016-05') + .reply(200, fs.readFileSync(`${__dirname}/../fixtures/statement.pdf`)); + + return n26.statement('statement-2016-05', true).then((statement) => { + expect(statement).to.have.property('id', 'statement-2016-05'); + expect(statement).to.have.property('type', 'pdf'); + expect(statement).to.have.property('pdf'); + expect(Buffer.isBuffer(statement.pdf)).to.be.true(); + + expect(apiStatements.isDone()).to.be.true(); + }); + }); + + it('should return error if no `id` is passed', () => { + return n26.statement().catch((err) => { + expect(err).to.be.eql('MISSING_PARAMS'); + }); + }); +}); diff --git a/tests/fixtures/statement.pdf b/tests/fixtures/statement.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c87bc9fdda7c319f0cd60a2450c30757f7032d1a GIT binary patch literal 687 zcmY!laBVK3W2JNQu9in%JqFyQ!*2s@++c&Y7G=jElm_GOpIdngYruf zOHvgK^n+51^Gl18Q;ThE?0^7axG9?93i|#@S-~Z_3i^HuM*41%?zQrB`e(HR4X%7Y=cCydX27V$71XhHGqYBao|muA$usARJ#{><7Hl*!GB7b_ zaB@yg4pwIN?I@|6*p{DE=$SRqsiAvzQ?{2{fXn4`d<=P#@>XCk!0d$ul^KR_B7#!W z^uwbK6-*R>;o+H=l3EdMpkN-WADmg0s({ry`Ve0M12`8LT>8%WIiLA_sDE5<}zv|1%{Trx++J&-i!bzyTJq^n{dO{3>rH u|26;IC{TE;n1_d9&jhvxtii;~Ra}x-R8motn#RjzYz9i5s;>TSyj%dR!P0gB literal 0 HcmV?d00001 diff --git a/tests/index.js b/tests/index.js index 31514ed..dfb7412 100644 --- a/tests/index.js +++ b/tests/index.js @@ -132,5 +132,6 @@ describe('account', () => { require('./account/unpair'); require('./account/statuses'); require('./account/barzahlen'); + require('./account/statement'); require('./account/statements'); }); diff --git a/tests/unmock.js b/tests/unmock.js index 900a6ca..c75281c 100644 --- a/tests/unmock.js +++ b/tests/unmock.js @@ -184,7 +184,7 @@ const statementsProperties = [ 'year' ]; -describe('Create instance', function () { +describe('Create instance', function () { // eslint-disable-line func-names this.timeout(5000); let n26; @@ -398,7 +398,7 @@ describe('Create instance', function () { return n26.statements().then((statements) => { statements.forEach((statement) => { - statementsProperties.forEach(property => { + statementsProperties.forEach((property) => { expect(statement).to.have.deep.property(property); }); }); @@ -407,6 +407,28 @@ describe('Create instance', function () { }); }); + it('should get last statement file', function () { // eslint-disable-line func-names + this.timeout(25000); + + return n26.statements().then((statements) => statements[0].id) + .then(statementId => { + return Promise.all([ + n26.statement(statementId), + n26.statement(statementId, true) + ]); + }) + .spread((base64, pdf) => { + [base64, pdf].forEach((statement) => { + ['id', 'type', 'pdf'].forEach((property) => { + expect(statement).to.have.deep.property(property); + }); + }); + + expect(base64.pdf).to.be.a('String'); + expect(Buffer.isBuffer(pdf.pdf)).to.be.true(); + }); + }); + if (!process.env.INVITE ||!process.env.EMAIL) { xit('shoud send invitation'); } else { From 1307c677eff9dacc96b1c18be46701386891ff9d Mon Sep 17 00:00:00 2001 From: Pierrick Date: Tue, 7 Jun 2016 11:49:39 +0200 Subject: [PATCH 2/6] Get Contacts Issue #9 --- lib/account.js | 21 ++++++++++++++++ lib/api.js | 11 ++++++++ tests/account/contacts.js | 53 +++++++++++++++++++++++++++++++++++++++ tests/index.js | 1 + tests/unmock.js | 20 +++++++++++++++ 5 files changed, 106 insertions(+) create mode 100644 tests/account/contacts.js diff --git a/lib/account.js b/lib/account.js index 64cf7f3..9119db8 100644 --- a/lib/account.js +++ b/lib/account.js @@ -239,6 +239,18 @@ const utils = require('./utils'); * @property {Number} year */ +/** + * @typedef contact + * + * @property {String} id + * @property {String} name + * @property {String} subtitle + * @property {Object} account + * @property {String} account.accountType + * @property {String} account.iban + * @property {String} account.bic + */ + /** * Number26 Account */ @@ -317,6 +329,15 @@ class Account { return utils.callApi(this, 'getCards'); } + /** + * Get contacts + * + * @return {Promise} + */ + contacts() { + return utils.callApi(this, 'getContacts'); + } + /** * Get / send invitations emails * diff --git a/lib/api.js b/lib/api.js index 61e1137..cbe3104 100644 --- a/lib/api.js +++ b/lib/api.js @@ -114,6 +114,17 @@ module.exports = { .catch(errorHandler); }, + getContacts(token) { + return request.get({ + url: `${api}/api/smrt/contacts`, + json: true, + headers: { + Authorization: `Bearer ${token}` + } + }) + .catch(errorHandler); + }, + getMe(token, options) { const qs = {}; if (options.full) { diff --git a/tests/account/contacts.js b/tests/account/contacts.js new file mode 100644 index 0000000..2ad0d72 --- /dev/null +++ b/tests/account/contacts.js @@ -0,0 +1,53 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('contacts', () => { + let api; + const dataContacts = [{ + id: 'c22ed0fa-2b24-48cf-a0dc-5df87b71f413', + name: 'POULPE GEORGE', + subtitle: 'NL84 DLBK 0283 8859 17', + account: { + accountType: 'sepa', + iban: 'NL84DLBK0283885917', + bic: 'ABNANL2A' + } + }]; + + beforeEach(() => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/smrt/contacts') + .reply(200, dataContacts); + }); + + it('should return account', () => { + return n26.contacts().then((contacts) => { + expect(contacts).to.be.eql(dataContacts); + }); + }); + + afterEach((done) => { + done((!api.isDone()) ? new Error('Request not done') : null); + }); +}); diff --git a/tests/index.js b/tests/index.js index dfb7412..48f5659 100644 --- a/tests/index.js +++ b/tests/index.js @@ -120,6 +120,7 @@ describe('Static', () => { describe('account', () => { require('./account/auth'); require('./account/memo'); + require('./account/contacts'); require('./account/createTransfer'); require('./account/getAccount'); require('./account/getAddresses'); diff --git a/tests/unmock.js b/tests/unmock.js index c75281c..d17b849 100644 --- a/tests/unmock.js +++ b/tests/unmock.js @@ -183,6 +183,14 @@ const statementsProperties = [ 'visibleTS', 'year' ]; +const contactsProperties = [ + 'id', + 'name', + 'subtitle', + 'account.accountType', + 'account.iban', + 'account.bic' +]; describe('Create instance', function () { // eslint-disable-line func-names this.timeout(5000); @@ -394,6 +402,18 @@ describe('Create instance', function () { // eslint-disable-line func-names }); }); + it('should get contacts', () => { + return n26.contacts().then((contacts) => { + contacts.forEach((contact) => { + contactsProperties.forEach(property => { + expect(contact).to.have.deep.property(property); + }); + }); + + console.log(`\tFirst contacts: ${contacts[0].name} ${contacts[0].subtitle}`); + }); + }); + it('should return statements', () => { return n26.statements().then((statements) => { From 927c075df7e170464835ccdb5a91909c32e92254 Mon Sep 17 00:00:00 2001 From: Pierrick Date: Tue, 7 Jun 2016 16:37:11 +0200 Subject: [PATCH 3/6] Get / Set limits account Issue #13 --- lib/account.js | 56 ++++++++++++++++++++++++++++ lib/api.js | 21 +++++++++++ tests/account/limits.js | 81 +++++++++++++++++++++++++++++++++++++++++ tests/index.js | 1 + tests/unmock.js | 31 ++++++++++++++++ 5 files changed, 190 insertions(+) create mode 100644 tests/account/limits.js diff --git a/lib/account.js b/lib/account.js index 9119db8..99312e0 100644 --- a/lib/account.js +++ b/lib/account.js @@ -251,6 +251,13 @@ const utils = require('./utils'); * @property {String} account.bic */ +/** + * @typedef limit + * + * @property {String} limit Limit type, can be ATM_DAILY_ACCOUNT or POS_DAILY_ACCOUNT + * @property {Number} amount + */ + /** * Number26 Account */ @@ -354,6 +361,55 @@ class Account { return utils.callApi(this, 'getInvitations'); } + /** + * Get / Set limits + * + * @param {Object} [limits] + * @param {Number} [limits.atm] Set daily limit for ATM withdraw + * @param {Number} [limits.pos] Set daily limit for POS payment + * + * @return {Promise|Promise} + */ + limits(limits) { + function validateAmount(amount, max) { + if (!Number.isInteger(amount) || amount < 0 || amount > max) { + return false; + } + + return true; + } + + if (limits) { + const calls = []; + + if (limits.atm !== undefined) { + if (!validateAmount(limits.atm, 2500)) { + return Promise.reject('Limits should be between 0 and 2500'); + } + + calls.push(utils.callApi(this, 'setLimits', { + limit: 'ATM_DAILY_ACCOUNT', + amount: limits.atm + })); + } + + if (limits.pos !== undefined) { + if (!validateAmount(limits.pos, 5000)) { + return Promise.reject('Limits should be between 0 and 5000'); + } + + calls.push(utils.callApi(this, 'setLimits', { + limit: 'POS_DAILY_ACCOUNT', + amount: limits.pos + })); + } + + return Promise.all(calls); + } + + return utils.callApi(this, 'getLimits'); + } + /** * Get information about current user * diff --git a/lib/api.js b/lib/api.js index cbe3104..e9ffd75 100644 --- a/lib/api.js +++ b/lib/api.js @@ -125,6 +125,17 @@ module.exports = { .catch(errorHandler); }, + getLimits(token) { + return request.get({ + url: `${api}/api/settings/account/limits`, + json: true, + headers: { + Authorization: `Bearer ${token}` + } + }) + .catch(errorHandler); + }, + getMe(token, options) { const qs = {}; if (options.full) { @@ -276,6 +287,16 @@ module.exports = { }); }, + setLimits(token, limits) { + return request.post({ + url: `${api}/api/settings/account/limits`, + json: limits, + headers: { + Authorization: `Bearer ${token}` + } + }); + }, + /* Pairing / unpairing */ diff --git a/tests/account/limits.js b/tests/account/limits.js new file mode 100644 index 0000000..e7e1c39 --- /dev/null +++ b/tests/account/limits.js @@ -0,0 +1,81 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('limits', () => { + it('should get limits', () => { + const api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/settings/account/limits') + .reply(200, [{ + limit: 'ATM_DAILY_ACCOUNT', + amount: 2500 + }, { + limit: 'POS_DAILY_ACCOUNT', + amount: 5000 + }]); + + return n26.limits().then((limits) => { + expect(limits).to.be.eql([{ + limit: 'ATM_DAILY_ACCOUNT', + amount: 2500 + }, { + limit: 'POS_DAILY_ACCOUNT', + amount: 5000 + }]); + + expect(api.isDone()).to.be.ok(); + }); + }); + + it('should set limits', () => { + const apiAtm = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .post('/api/settings/account/limits', {limit: 'ATM_DAILY_ACCOUNT', amount: 200}) + .reply(200); + + const apiPos = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .post('/api/settings/account/limits', {limit: 'POS_DAILY_ACCOUNT', amount: 0}) + .reply(200); + + return n26.limits({ + atm: 200, + pos: 0 + }).then(() => { + expect(apiAtm.isDone()).to.be.ok(); + expect(apiPos.isDone()).to.be.ok(); + }); + }); + + it('should return error is setting a bad value limits', () => { + return n26.limits({atm: 50000}).catch((err) => { + expect(err).to.be.eql('Limits should be between 0 and 2500'); + }); + }); +}); diff --git a/tests/index.js b/tests/index.js index 48f5659..a0b4c45 100644 --- a/tests/index.js +++ b/tests/index.js @@ -130,6 +130,7 @@ describe('account', () => { require('./account/getTransactions'); require('./account/getTransaction'); require('./account/invitations'); + require('./account/limits'); require('./account/unpair'); require('./account/statuses'); require('./account/barzahlen'); diff --git a/tests/unmock.js b/tests/unmock.js index d17b849..c3b3f61 100644 --- a/tests/unmock.js +++ b/tests/unmock.js @@ -402,6 +402,37 @@ describe('Create instance', function () { // eslint-disable-line func-names }); }); + it('should get account limits', () => { + return n26.limits().then((limits) => { + console.log(limits) + + console.log(`\tYour account is limited to ${limits[0].amount} for ${limits[0].limit}`); + }); + }); + + it('should set account limits', () => { + let previousAtmDailyAccount; + + return n26.limits().then((limits) => { + limits.forEach((limit) => { + if (limit.limit === 'ATM_DAILY_ACCOUNT') { + previousAtmDailyAccount = limit.amount; + } + }); + }) + .then(() => n26.limits({atm: 500})) + .then(() => n26.limits()) + .then((limits) => { + limits.forEach((limit) => { + if (limit.limit === 'ATM_DAILY_ACCOUNT') { + expect(limit.amount).to.be.eql(500); + } + }); + + return n26.limits({atm: previousAtmDailyAccount}); + }); + }); + it('should get contacts', () => { return n26.contacts().then((contacts) => { contacts.forEach((contact) => { From 12c3a66f3389491ef01c9cd6b1e05ad83b30ab1e Mon Sep 17 00:00:00 2001 From: Pierrick Date: Tue, 7 Jun 2016 17:00:02 +0200 Subject: [PATCH 4/6] Update docdash / eslint-config-airbnb --- .eslintrc | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index 2e49b44..0c98e4d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,5 +10,5 @@ "node": true, "mocha": true }, - "extends": "airbnb" + "extends": "airbnb-base" } diff --git a/package.json b/package.json index 47ef8b4..4c403c2 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,9 @@ "chai": "^3.2.0", "coveralls": "^2.11.9", "dirty-chai": "^1.2.2", - "docdash": "^0.3.0", + "docdash": "^0.4.0", "eslint": "^2.8.0", - "eslint-config-airbnb": "^8.0.0", + "eslint-config-airbnb-base": "^3.0.1", "eslint-plugin-import": "^1.5.0", "istanbul": "^0.4.2", "jsdoc": "^3.4.0", From b7288e9118f5d7b23cc62f29b8914bc36833c0a9 Mon Sep 17 00:00:00 2001 From: Pierrick Date: Tue, 7 Jun 2016 18:11:08 +0200 Subject: [PATCH 5/6] Correctly thow errors Rename somes tests for correspond to func name --- lib/account.js | 126 +++++++------ tests/account/account.js | 57 ++++++ tests/account/addresses.js | 89 ++++++++++ tests/account/auth.js | 3 +- tests/account/barzahlen.js | 53 +++--- tests/account/cards.js | 71 ++++++++ tests/account/getAccount.js | 59 ------- tests/account/getAddresses.js | 91 ---------- tests/account/getCards.js | 73 -------- tests/account/getMe.js | 105 ----------- tests/account/getRecipients.js | 53 ------ tests/account/getTransactions.js | 165 ------------------ tests/account/limits.js | 3 +- tests/account/me.js | 103 +++++++++++ tests/account/recipients.js | 51 ++++++ tests/account/statement.js | 3 +- .../{getTransaction.js => transaction.js} | 2 +- tests/account/transactions.js | 163 +++++++++++++++++ .../{createTransfer.js => transfer.js} | 8 +- tests/index.js | 24 +-- tests/unmock.js | 13 +- 21 files changed, 656 insertions(+), 659 deletions(-) create mode 100644 tests/account/account.js create mode 100644 tests/account/addresses.js create mode 100644 tests/account/cards.js delete mode 100644 tests/account/getAccount.js delete mode 100644 tests/account/getAddresses.js delete mode 100644 tests/account/getCards.js delete mode 100644 tests/account/getMe.js delete mode 100644 tests/account/getRecipients.js delete mode 100644 tests/account/getTransactions.js create mode 100644 tests/account/me.js create mode 100644 tests/account/recipients.js rename tests/account/{getTransaction.js => transaction.js} (99%) create mode 100644 tests/account/transactions.js rename tests/account/{createTransfer.js => transfer.js} (89%) diff --git a/lib/account.js b/lib/account.js index 99312e0..a91b488 100644 --- a/lib/account.js +++ b/lib/account.js @@ -379,35 +379,37 @@ class Account { return true; } - if (limits) { - const calls = []; - - if (limits.atm !== undefined) { - if (!validateAmount(limits.atm, 2500)) { - return Promise.reject('Limits should be between 0 and 2500'); + return Promise.try(() => { + if (limits) { + const calls = []; + + if (limits.atm !== undefined) { + if (!validateAmount(limits.atm, 2500)) { + throw new Error('Limits should be between 0 and 2500'); + } + + calls.push(utils.callApi(this, 'setLimits', { + limit: 'ATM_DAILY_ACCOUNT', + amount: limits.atm + })); } - calls.push(utils.callApi(this, 'setLimits', { - limit: 'ATM_DAILY_ACCOUNT', - amount: limits.atm - })); - } + if (limits.pos !== undefined) { + if (!validateAmount(limits.pos, 5000)) { + throw new Error('Limits should be between 0 and 5000'); + } - if (limits.pos !== undefined) { - if (!validateAmount(limits.pos, 5000)) { - return Promise.reject('Limits should be between 0 and 5000'); + calls.push(utils.callApi(this, 'setLimits', { + limit: 'POS_DAILY_ACCOUNT', + amount: limits.pos + })); } - calls.push(utils.callApi(this, 'setLimits', { - limit: 'POS_DAILY_ACCOUNT', - amount: limits.pos - })); + return Promise.all(calls); } - return Promise.all(calls); - } - - return utils.callApi(this, 'getLimits'); + return utils.callApi(this, 'getLimits'); + }); } /** @@ -440,18 +442,18 @@ class Account { * @return {Promise} */ statement(id, pdf) { - pdf = !!pdf; - if (!id) { - return Promise.reject('MISSING_PARAMS'); - } + return Promise.try(() => { + pdf = !!pdf; + if (!id) { + throw new Error('MISSING_PARAMS'); + } - return utils.callApi(this, 'getStatement', {id, pdf}) - .then(result => { - return { + return utils.callApi(this, 'getStatement', {id, pdf}) + .then(result => ({ id, type: (pdf) ? 'pdf' : 'base64', pdf: (pdf) ? new Buffer(result, 'binary') : result.pdf - }; + })); }); } @@ -511,17 +513,19 @@ class Account { * @return {Promise} */ transaction(id, options) { - if (!id) { - return Promise.reject('MISSING_PARAMS'); - } + return Promise.try(() => { + if (!id) { + throw new Error('MISSING_PARAMS'); + } - const data = {id}; + const data = {id}; - if (options && options.meta) { - data.meta = options.meta; - } + if (options && options.meta) { + data.meta = options.meta; + } - return utils.callApi(this, 'getTransaction', data); + return utils.callApi(this, 'getTransaction', data); + }); } /** @@ -538,15 +542,17 @@ class Account { * @return {Promise} */ transfer(data) { - if (!data.pin || !data.iban || !data.bic || !data.amount || !data.name || !data.reference) { - return Promise.reject('MISSING_PARAMS'); - } + return Promise.try(() => { + if (!data.pin || !data.iban || !data.bic || !data.amount || !data.name || !data.reference) { + throw new Error('MISSING_PARAMS'); + } - if (data.reference.length > 135) { - return Promise.reject('REFERENCE_TOO_LONG'); - } + if (data.reference.length > 135) { + throw new Error('REFERENCE_TOO_LONG'); + } - return utils.callApi(this, 'createTransfer', data); + return utils.callApi(this, 'createTransfer', data); + }); } /** @@ -560,17 +566,19 @@ class Account { * @return {Promise} */ unpairInit(pin, cardNumber) { - const that = this; + return Promise.try(() => { + const that = this; - if (!pin || !cardNumber) { - return Promise.reject('MISSING_PARAMS'); - } + if (!pin || !cardNumber) { + throw new Error('MISSING_PARAMS'); + } - return utils.callApi(that, 'unpairUpstart') - .then(link => utils.callApi(that, 'unpairVerify', link)) - .then(() => utils.callApi(that, 'unpairValidationPin', pin)) - .then(() => utils.callApi(that, 'unpairValidationCard', cardNumber)) - .then(() => utils.callApi(that, 'unpairValidationSms')); + return utils.callApi(that, 'unpairUpstart') + .then(link => utils.callApi(that, 'unpairVerify', link)) + .then(() => utils.callApi(that, 'unpairValidationPin', pin)) + .then(() => utils.callApi(that, 'unpairValidationCard', cardNumber)) + .then(() => utils.callApi(that, 'unpairValidationSms')); + }); } /** @@ -584,11 +592,13 @@ class Account { * @return {Promise} */ unpairConfirm(smsNumber) { - if (!smsNumber) { - return Promise.reject('MISSING_PARAMS'); - } + return Promise.try(() => { + if (!smsNumber) { + throw new Error('MISSING_PARAMS'); + } - return utils.callApi(this, 'unpairValidationSmsVerify', smsNumber); + return utils.callApi(this, 'unpairValidationSmsVerify', smsNumber); + }); } } diff --git a/tests/account/account.js b/tests/account/account.js new file mode 100644 index 0000000..53a5fd2 --- /dev/null +++ b/tests/account/account.js @@ -0,0 +1,57 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('account', () => { + let api; + + beforeEach(() => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/accounts') + .reply(200, { + status: 'OPEN_PRIMARY_ACCOUNT', + availableBalance: 42.42, + usableBalance: 42.42, + bankBalance: 4242.00, + iban: 'NL72SNSB0931762238', + id: 'e112c309-80df-4016-8079-93ffdea8300e' + }); + }); + + it('should return account', () => { + return n26.account().then((account) => { + expect(account).to.be.eql({ + status: 'OPEN_PRIMARY_ACCOUNT', + availableBalance: 42.42, + usableBalance: 42.42, + bankBalance: 4242.00, + iban: 'NL72SNSB0931762238', + id: 'e112c309-80df-4016-8079-93ffdea8300e' + }); + }); + }); + + afterEach((done) => { + done((!api.isDone()) ? new Error('Request not done') : null); + }); +}); diff --git a/tests/account/addresses.js b/tests/account/addresses.js new file mode 100644 index 0000000..7103b9e --- /dev/null +++ b/tests/account/addresses.js @@ -0,0 +1,89 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('addresses', () => { + let api; + + beforeEach(() => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/addresses') + .reply(200, { + paging: { + totalResults: 2 + }, + data: [{ + addressLine1: 'Maëlys Roux', + streetName: 'Rue du chat qui pêche', + houseNumberBlock: '1', + zipCode: '75001', + cityName: 'PARIS', + countryName: 'FRA', + type: 'PASSPORT', + id: '78b7506b-06ae-4b47-80a7-be300acb3175' + }, { + addressLine1: '', + streetName: 'Rue de la roquette', + houseNumberBlock: '42', + zipCode: '75011', + cityName: 'Paris', + countryName: 'FRA', + type: 'SHIPPING', + id: 'ad1932e4-a968-454d-a64b-11476d6fa34a' + }] + }); + }); + + it('should return addresses', () => { + return n26.addresses().then((account) => { + expect(account).to.be.eql({ + paging: { + totalResults: 2 + }, + data: [{ + addressLine1: 'Maëlys Roux', + streetName: 'Rue du chat qui pêche', + houseNumberBlock: '1', + zipCode: '75001', + cityName: 'PARIS', + countryName: 'FRA', + type: 'PASSPORT', + id: '78b7506b-06ae-4b47-80a7-be300acb3175' + }, { + addressLine1: '', + streetName: 'Rue de la roquette', + houseNumberBlock: '42', + zipCode: '75011', + cityName: 'Paris', + countryName: 'FRA', + type: 'SHIPPING', + id: 'ad1932e4-a968-454d-a64b-11476d6fa34a' + }] + }); + }); + }); + + afterEach((done) => { + done((!api.isDone()) ? new Error('Request not done') : null); + }); +}); diff --git a/tests/account/auth.js b/tests/account/auth.js index 07c620d..3c58db4 100644 --- a/tests/account/auth.js +++ b/tests/account/auth.js @@ -39,7 +39,8 @@ describe('auth', () => { 'Content-Type': 'application/json' }) .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/me').reply(200, { + .get('/api/me') + .reply(200, { email: 'g.loutre@mail.com', firstName: 'George', lastName: 'loutre', diff --git a/tests/account/barzahlen.js b/tests/account/barzahlen.js index 3ca723d..acefdff 100644 --- a/tests/account/barzahlen.js +++ b/tests/account/barzahlen.js @@ -19,33 +19,32 @@ beforeEach((done) => { }); describe('barzahlen', () => { - describe('Success', () => { - const dataBarzahlen = { - depositAllowance: '999.0', - withdrawAllowance: '999.0', - remainingAmountMonth: '100.0', - feeRate: '0.015', - cash26WithdrawalsCount: '0', - cash26WithdrawalsSum: '0', - atmWithdrawalsCount: '3', - atmWithdrawalsSum: '80.0', - monthlyDepositFeeThreshold: '100.0', - success: false - }; - it('should return barzahlen', () => { - const apiBarzahlen = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/barzahlen/check') - .reply(200, dataBarzahlen); - - return n26.barzahlen().then((barzahlen) => { - expect(barzahlen).to.be.eql(dataBarzahlen); - - expect(apiBarzahlen.isDone()).to.be.true(); - }); + const dataBarzahlen = { + depositAllowance: '999.0', + withdrawAllowance: '999.0', + remainingAmountMonth: '100.0', + feeRate: '0.015', + cash26WithdrawalsCount: '0', + cash26WithdrawalsSum: '0', + atmWithdrawalsCount: '3', + atmWithdrawalsSum: '80.0', + monthlyDepositFeeThreshold: '100.0', + success: false + }; + + it('should return barzahlen', () => { + const apiBarzahlen = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/barzahlen/check') + .reply(200, dataBarzahlen); + + return n26.barzahlen().then((barzahlen) => { + expect(barzahlen).to.be.eql(dataBarzahlen); + + expect(apiBarzahlen.isDone()).to.be.true(); }); }); }); diff --git a/tests/account/cards.js b/tests/account/cards.js new file mode 100644 index 0000000..8ea3467 --- /dev/null +++ b/tests/account/cards.js @@ -0,0 +1,71 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('cards', () => { + let api; + + beforeEach(() => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/cards') + .reply(200, { + paging: { + totalResults: 1 + }, + data: [{ + maskedPan: '517337******4242', + expirationDate: 1548870576000, + cardType: 'MASTERCARD', + n26Status: 'ACTIVE', + pinDefined: 1454698655841, + cardActivated: 1454698679301, + usernameOnCard: 'GEORGE LOUTRE', + id: '203f3cc1-1bbb-4a3a-861c-2ac21fd8a77e' + }] + }); + }); + + it('should return cards', () => { + return n26.cards().then((account) => { + expect(account).to.be.eql({ + paging: { + totalResults: 1 + }, + data: [{ + maskedPan: '517337******4242', + expirationDate: 1548870576000, + cardType: 'MASTERCARD', + n26Status: 'ACTIVE', + pinDefined: 1454698655841, + cardActivated: 1454698679301, + usernameOnCard: 'GEORGE LOUTRE', + id: '203f3cc1-1bbb-4a3a-861c-2ac21fd8a77e' + }] + }); + }); + }); + + afterEach((done) => { + done((!api.isDone()) ? new Error('Request not done') : null); + }); +}); diff --git a/tests/account/getAccount.js b/tests/account/getAccount.js deleted file mode 100644 index 65349d1..0000000 --- a/tests/account/getAccount.js +++ /dev/null @@ -1,59 +0,0 @@ -'use strict'; -/* eslint-disable global-require, max-len, arrow-body-style */ -const nock = require('nock'); -const chai = require('chai'); -const dirtyChai = require('dirty-chai'); -const expect = chai.expect; - -chai.use(dirtyChai); - -let n26; -const data = require('../fixtures/data'); - -beforeEach((done) => { - require('../fixtures/auth')((err, m) => { - n26 = m; - - done(); - }); -}); - -describe('getAccount', () => { - describe('Success', () => { - let api; - - beforeEach(() => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/accounts') - .reply(200, { - status: 'OPEN_PRIMARY_ACCOUNT', - availableBalance: 42.42, - usableBalance: 42.42, - bankBalance: 4242.00, - iban: 'NL72SNSB0931762238', - id: 'e112c309-80df-4016-8079-93ffdea8300e' - }); - }); - - it('should return account', () => { - return n26.account().then((account) => { - expect(account).to.be.eql({ - status: 'OPEN_PRIMARY_ACCOUNT', - availableBalance: 42.42, - usableBalance: 42.42, - bankBalance: 4242.00, - iban: 'NL72SNSB0931762238', - id: 'e112c309-80df-4016-8079-93ffdea8300e' - }); - }); - }); - - afterEach((done) => { - done((!api.isDone()) ? new Error('Request not done') : null); - }); - }); -}); diff --git a/tests/account/getAddresses.js b/tests/account/getAddresses.js deleted file mode 100644 index 18232fe..0000000 --- a/tests/account/getAddresses.js +++ /dev/null @@ -1,91 +0,0 @@ -'use strict'; -/* eslint-disable global-require, max-len, arrow-body-style */ -const nock = require('nock'); -const chai = require('chai'); -const dirtyChai = require('dirty-chai'); -const expect = chai.expect; - -chai.use(dirtyChai); - -let n26; -const data = require('../fixtures/data'); - -beforeEach((done) => { - require('../fixtures/auth')((err, m) => { - n26 = m; - - done(); - }); -}); - -describe('getAddresses', () => { - describe('Success', () => { - let api; - - beforeEach(() => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/addresses') - .reply(200, { - paging: { - totalResults: 2 - }, - data: [{ - addressLine1: 'Maëlys Roux', - streetName: 'Rue du chat qui pêche', - houseNumberBlock: '1', - zipCode: '75001', - cityName: 'PARIS', - countryName: 'FRA', - type: 'PASSPORT', - id: '78b7506b-06ae-4b47-80a7-be300acb3175' - }, { - addressLine1: '', - streetName: 'Rue de la roquette', - houseNumberBlock: '42', - zipCode: '75011', - cityName: 'Paris', - countryName: 'FRA', - type: 'SHIPPING', - id: 'ad1932e4-a968-454d-a64b-11476d6fa34a' - }] - }); - }); - - it('should return addresses', () => { - return n26.addresses().then((account) => { - expect(account).to.be.eql({ - paging: { - totalResults: 2 - }, - data: [{ - addressLine1: 'Maëlys Roux', - streetName: 'Rue du chat qui pêche', - houseNumberBlock: '1', - zipCode: '75001', - cityName: 'PARIS', - countryName: 'FRA', - type: 'PASSPORT', - id: '78b7506b-06ae-4b47-80a7-be300acb3175' - }, { - addressLine1: '', - streetName: 'Rue de la roquette', - houseNumberBlock: '42', - zipCode: '75011', - cityName: 'Paris', - countryName: 'FRA', - type: 'SHIPPING', - id: 'ad1932e4-a968-454d-a64b-11476d6fa34a' - }] - }); - }); - }); - - afterEach((done) => { - done((!api.isDone()) ? new Error('Request not done') : null); - }); - }); -}); diff --git a/tests/account/getCards.js b/tests/account/getCards.js deleted file mode 100644 index 98914b6..0000000 --- a/tests/account/getCards.js +++ /dev/null @@ -1,73 +0,0 @@ -'use strict'; -/* eslint-disable global-require, max-len, arrow-body-style */ -const nock = require('nock'); -const chai = require('chai'); -const dirtyChai = require('dirty-chai'); -const expect = chai.expect; - -chai.use(dirtyChai); - -let n26; -const data = require('../fixtures/data'); - -beforeEach((done) => { - require('../fixtures/auth')((err, m) => { - n26 = m; - - done(); - }); -}); - -describe('getCards', () => { - describe('Success', () => { - let api; - - beforeEach(() => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/cards') - .reply(200, { - paging: { - totalResults: 1 - }, - data: [{ - maskedPan: '517337******4242', - expirationDate: 1548870576000, - cardType: 'MASTERCARD', - n26Status: 'ACTIVE', - pinDefined: 1454698655841, - cardActivated: 1454698679301, - usernameOnCard: 'GEORGE LOUTRE', - id: '203f3cc1-1bbb-4a3a-861c-2ac21fd8a77e' - }] - }); - }); - - it('should return cards', () => { - return n26.cards().then((account) => { - expect(account).to.be.eql({ - paging: { - totalResults: 1 - }, - data: [{ - maskedPan: '517337******4242', - expirationDate: 1548870576000, - cardType: 'MASTERCARD', - n26Status: 'ACTIVE', - pinDefined: 1454698655841, - cardActivated: 1454698679301, - usernameOnCard: 'GEORGE LOUTRE', - id: '203f3cc1-1bbb-4a3a-861c-2ac21fd8a77e' - }] - }); - }); - }); - - afterEach((done) => { - done((!api.isDone()) ? new Error('Request not done') : null); - }); - }); -}); diff --git a/tests/account/getMe.js b/tests/account/getMe.js deleted file mode 100644 index 082eba3..0000000 --- a/tests/account/getMe.js +++ /dev/null @@ -1,105 +0,0 @@ -'use strict'; -/* eslint-disable global-require, max-len, arrow-body-style */ -const nock = require('nock'); -const chai = require('chai'); -const dirtyChai = require('dirty-chai'); -const expect = chai.expect; - -chai.use(dirtyChai); - -let n26; -const data = require('../fixtures/data'); - -beforeEach((done) => { - require('../fixtures/auth')((err, m) => { - n26 = m; - - done(); - }); -}); - -describe('getMe', () => { - describe('Success', () => { - it('should return me', () => { - const apiMe = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/me') - .reply(200, { - email: 'g.loutre@mail.com', - firstName: 'George', - lastName: 'loutre', - kycFirstName: 'George', - kycLastName: 'Loutre', - title: '', - gender: 'MALE', - birthDate: 602380800000, - passwordHash: '$2a$10$YIxk0A.QvM7sym42k7xjUuCePrW3xmrqnzjcl5aleWD9A0bThXGkq', - signupCompleted: true, - nationality: 'FRA', - birthPlace: 'PARIS', - mobilePhoneNumber: '+3364242424242', - taxIDRequired: true, - shadowID: '184be12-7e88-4cbe-a461-a7776bd2664d', - id: '184be12-7e88-4cbe-a461-a7776bd2664d' - }); - - return n26.me().then((me) => { - expect(me).to.be.eql({ - email: 'g.loutre@mail.com', - firstName: 'George', - lastName: 'loutre', - kycFirstName: 'George', - kycLastName: 'Loutre', - title: '', - gender: 'MALE', - birthDate: 602380800000, - passwordHash: '$2a$10$YIxk0A.QvM7sym42k7xjUuCePrW3xmrqnzjcl5aleWD9A0bThXGkq', - signupCompleted: true, - nationality: 'FRA', - birthPlace: 'PARIS', - mobilePhoneNumber: '+3364242424242', - taxIDRequired: true, - shadowID: '184be12-7e88-4cbe-a461-a7776bd2664d', - id: '184be12-7e88-4cbe-a461-a7776bd2664d' - }); - - expect(apiMe.isDone()).to.be.true(); - }); - }); - - it('should return me with full option', () => { - const apiMe = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/me') - .query({full: true}) - .reply(200, { - email: 'g.loutre@mail.com', - firstName: 'George', - lastName: 'loutre', - kycFirstName: 'George', - kycLastName: 'Loutre', - title: '', - gender: 'MALE', - birthDate: 602380800000, - passwordHash: '$2a$10$YIxk0A.QvM7sym42k7xjUuCePrW3xmrqnzjcl5aleWD9A0bThXGkq', - signupCompleted: true, - nationality: 'FRA', - birthPlace: 'PARIS', - mobilePhoneNumber: '+3364242424242', - taxIDRequired: true, - shadowID: '184be12-7e88-4cbe-a461-a7776bd2664d', - id: '184be12-7e88-4cbe-a461-a7776bd2664d' - }); - - return n26.me(true).then(() => { - expect(apiMe.isDone()).to.be.true(); - }); - }); - }); -}); diff --git a/tests/account/getRecipients.js b/tests/account/getRecipients.js deleted file mode 100644 index 7ab2ef7..0000000 --- a/tests/account/getRecipients.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; -/* eslint-disable global-require, max-len, arrow-body-style */ -const nock = require('nock'); -const chai = require('chai'); -const dirtyChai = require('dirty-chai'); -const expect = chai.expect; - -chai.use(dirtyChai); - -let n26; -const data = require('../fixtures/data'); - -beforeEach((done) => { - require('../fixtures/auth')((err, m) => { - n26 = m; - - done(); - }); -}); - -describe('getRecipients', () => { - describe('Success', () => { - let api; - - beforeEach(() => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/transactions/recipients') - .reply(200, [{ - iban: 'NL20ABNA0581855476', - name: 'DUPONT MICHEL', - bic: 'ABNANL2A' - }]); - }); - - it('should return recipients', () => { - return n26.recipients().then((recipients) => { - expect(recipients).to.be.eql([{ - iban: 'NL20ABNA0581855476', - name: 'DUPONT MICHEL', - bic: 'ABNANL2A' - }]); - }); - }); - - afterEach((done) => { - done((!api.isDone()) ? new Error('Request not done') : null); - }); - }); -}); diff --git a/tests/account/getTransactions.js b/tests/account/getTransactions.js deleted file mode 100644 index f126175..0000000 --- a/tests/account/getTransactions.js +++ /dev/null @@ -1,165 +0,0 @@ -'use strict'; -/* eslint-disable global-require, max-len, arrow-body-style */ -const nock = require('nock'); -const chai = require('chai'); -const dirtyChai = require('dirty-chai'); -const expect = chai.expect; - -chai.use(dirtyChai); - -let n26; -const data = require('../fixtures/data'); - -beforeEach((done) => { - require('../fixtures/auth')((err, m) => { - n26 = m; - - done(); - }); -}); - -describe('getTransactions', () => { - describe('Success', () => { - let api; - - it('should return transactions', () => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/smrt/transactions') - .query({limit: 50, pending: false}) - .reply(200, [{ - id: 'bbd24eb7-925a-48dd-9c1e-75bb9f514d78', - type: 'AA', - smartLinkId: '1125318169-598002', - amount: -21.79, - currencyCode: 'EUR', - originalAmount: -21.79, - originalCurrency: 'EUR', - exchangeRate: 1.0, - merchantCity: 'PARIS ', - visibleTS: 1455292872000, - mcc: 5977, - mccGroup: 4, - merchantName: 'PANDORA CORP ', - merchantId: '6260861 ', - recurring: false, - userId: '93c3e18b-830a-4758-bb96-ef4d1d859fc3', - linkId: '1125318169-598002', - accountId: 'efe2cc9a-49da-4eea-bfa0-236eac673a8a', - category: 'micro-shopping', - cardId: '9d1e122f-76ea-4222-a059-a92348a40ac2', - pending: false, - transactionNature: 'NORMAL' - }]); - - return n26.transactions({}).then((me) => { - expect(me).to.be.eql([{ - id: 'bbd24eb7-925a-48dd-9c1e-75bb9f514d78', - type: 'AA', - smartLinkId: '1125318169-598002', - amount: -21.79, - currencyCode: 'EUR', - originalAmount: -21.79, - originalCurrency: 'EUR', - exchangeRate: 1.0, - merchantCity: 'PARIS ', - visibleTS: 1455292872000, - mcc: 5977, - mccGroup: 4, - merchantName: 'PANDORA CORP ', - merchantId: '6260861 ', - recurring: false, - userId: '93c3e18b-830a-4758-bb96-ef4d1d859fc3', - linkId: '1125318169-598002', - accountId: 'efe2cc9a-49da-4eea-bfa0-236eac673a8a', - category: 'micro-shopping', - cardId: '9d1e122f-76ea-4222-a059-a92348a40ac2', - pending: false, - transactionNature: 'NORMAL' - }]); - }); - }); - - it('should limit result', () => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/smrt/transactions') - .query({limit: 20, pending: false}) - .reply(200, [{ - id: 'bbd24eb7-925a-48dd-9c1e-75bb9f514d78', - type: 'AA', - smartLinkId: '1125318169-598002', - amount: -21.79, - currencyCode: 'EUR', - originalAmount: -21.79, - originalCurrency: 'EUR', - exchangeRate: 1.0, - merchantCity: 'PARIS ', - visibleTS: 1455292872000, - mcc: 5977, - mccGroup: 4, - merchantName: 'PANDORA CORP ', - merchantId: '6260861 ', - recurring: false, - userId: '93c3e18b-830a-4758-bb96-ef4d1d859fc3', - linkId: '1125318169-598002', - accountId: 'efe2cc9a-49da-4eea-bfa0-236eac673a8a', - category: 'micro-shopping', - cardId: '9d1e122f-76ea-4222-a059-a92348a40ac2', - pending: false, - transactionNature: 'NORMAL' - }]); - - return n26.transactions({limit: 20}); - }); - - it('should filter by categories result', () => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/smrt/transactions') - .query({limit: 50, categories: 'micro-education,micro-atm', pending: false}) - .reply(200, []); - - return n26.transactions({categories: ['micro-education', 'micro-atm']}); - }); - - it('should filter by date', () => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/smrt/transactions') - .query({limit: 50, from: 1454630400000, to: 1454803199999, pending: false}) - .reply(200, []); - - return n26.transactions({from: 1454630400000, to: 1454803199999}); - }); - - it('should filter by text', () => { - api = nock('https://api.tech26.de') - .defaultReplyHeaders({ - 'Content-Type': 'application/json' - }) - .matchHeader('Authorization', `Bearer ${data.access_token}`) - .get('/api/smrt/transactions') - .query({limit: 50, textFilter: 'loutre', pending: false}) - .reply(200, []); - - return n26.transactions({text: 'loutre'}); - }); - - afterEach((done) => { - done((!api.isDone()) ? new Error('Request not done') : null); - }); - }); -}); diff --git a/tests/account/limits.js b/tests/account/limits.js index e7e1c39..e30edc4 100644 --- a/tests/account/limits.js +++ b/tests/account/limits.js @@ -75,7 +75,8 @@ describe('limits', () => { it('should return error is setting a bad value limits', () => { return n26.limits({atm: 50000}).catch((err) => { - expect(err).to.be.eql('Limits should be between 0 and 2500'); + expect(err).to.be.an.instanceOf(Error); + expect(err.message).to.equal('Limits should be between 0 and 2500'); }); }); }); diff --git a/tests/account/me.js b/tests/account/me.js new file mode 100644 index 0000000..2a681e0 --- /dev/null +++ b/tests/account/me.js @@ -0,0 +1,103 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('me', () => { + it('should return me', () => { + const apiMe = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/me') + .reply(200, { + email: 'g.loutre@mail.com', + firstName: 'George', + lastName: 'loutre', + kycFirstName: 'George', + kycLastName: 'Loutre', + title: '', + gender: 'MALE', + birthDate: 602380800000, + passwordHash: '$2a$10$YIxk0A.QvM7sym42k7xjUuCePrW3xmrqnzjcl5aleWD9A0bThXGkq', + signupCompleted: true, + nationality: 'FRA', + birthPlace: 'PARIS', + mobilePhoneNumber: '+3364242424242', + taxIDRequired: true, + shadowID: '184be12-7e88-4cbe-a461-a7776bd2664d', + id: '184be12-7e88-4cbe-a461-a7776bd2664d' + }); + + return n26.me().then((me) => { + expect(me).to.be.eql({ + email: 'g.loutre@mail.com', + firstName: 'George', + lastName: 'loutre', + kycFirstName: 'George', + kycLastName: 'Loutre', + title: '', + gender: 'MALE', + birthDate: 602380800000, + passwordHash: '$2a$10$YIxk0A.QvM7sym42k7xjUuCePrW3xmrqnzjcl5aleWD9A0bThXGkq', + signupCompleted: true, + nationality: 'FRA', + birthPlace: 'PARIS', + mobilePhoneNumber: '+3364242424242', + taxIDRequired: true, + shadowID: '184be12-7e88-4cbe-a461-a7776bd2664d', + id: '184be12-7e88-4cbe-a461-a7776bd2664d' + }); + + expect(apiMe.isDone()).to.be.true(); + }); + }); + + it('should return me with full option', () => { + const apiMe = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/me') + .query({full: true}) + .reply(200, { + email: 'g.loutre@mail.com', + firstName: 'George', + lastName: 'loutre', + kycFirstName: 'George', + kycLastName: 'Loutre', + title: '', + gender: 'MALE', + birthDate: 602380800000, + passwordHash: '$2a$10$YIxk0A.QvM7sym42k7xjUuCePrW3xmrqnzjcl5aleWD9A0bThXGkq', + signupCompleted: true, + nationality: 'FRA', + birthPlace: 'PARIS', + mobilePhoneNumber: '+3364242424242', + taxIDRequired: true, + shadowID: '184be12-7e88-4cbe-a461-a7776bd2664d', + id: '184be12-7e88-4cbe-a461-a7776bd2664d' + }); + + return n26.me(true).then(() => { + expect(apiMe.isDone()).to.be.true(); + }); + }); +}); diff --git a/tests/account/recipients.js b/tests/account/recipients.js new file mode 100644 index 0000000..dfeffd3 --- /dev/null +++ b/tests/account/recipients.js @@ -0,0 +1,51 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('recipients', () => { + let api; + + beforeEach(() => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/transactions/recipients') + .reply(200, [{ + iban: 'NL20ABNA0581855476', + name: 'DUPONT MICHEL', + bic: 'ABNANL2A' + }]); + }); + + it('should return recipients', () => { + return n26.recipients().then((recipients) => { + expect(recipients).to.be.eql([{ + iban: 'NL20ABNA0581855476', + name: 'DUPONT MICHEL', + bic: 'ABNANL2A' + }]); + }); + }); + + afterEach((done) => { + done((!api.isDone()) ? new Error('Request not done') : null); + }); +}); diff --git a/tests/account/statement.js b/tests/account/statement.js index 70020cc..2d88851 100644 --- a/tests/account/statement.js +++ b/tests/account/statement.js @@ -62,7 +62,8 @@ describe('statement', () => { it('should return error if no `id` is passed', () => { return n26.statement().catch((err) => { - expect(err).to.be.eql('MISSING_PARAMS'); + expect(err).to.be.an.instanceOf(Error); + expect(err.message).to.equal('MISSING_PARAMS'); }); }); }); diff --git a/tests/account/getTransaction.js b/tests/account/transaction.js similarity index 99% rename from tests/account/getTransaction.js rename to tests/account/transaction.js index e9e440f..f3c7228 100644 --- a/tests/account/getTransaction.js +++ b/tests/account/transaction.js @@ -18,7 +18,7 @@ beforeEach((done) => { }); }); -describe('getTransaction', () => { +describe('transaction', () => { before(() => { nock.cleanAll(); }); diff --git a/tests/account/transactions.js b/tests/account/transactions.js new file mode 100644 index 0000000..13d27d1 --- /dev/null +++ b/tests/account/transactions.js @@ -0,0 +1,163 @@ +'use strict'; +/* eslint-disable global-require, max-len, arrow-body-style */ +const nock = require('nock'); +const chai = require('chai'); +const dirtyChai = require('dirty-chai'); +const expect = chai.expect; + +chai.use(dirtyChai); + +let n26; +const data = require('../fixtures/data'); + +beforeEach((done) => { + require('../fixtures/auth')((err, m) => { + n26 = m; + + done(); + }); +}); + +describe('transactions', () => { + let api; + + it('should return transactions', () => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/smrt/transactions') + .query({limit: 50, pending: false}) + .reply(200, [{ + id: 'bbd24eb7-925a-48dd-9c1e-75bb9f514d78', + type: 'AA', + smartLinkId: '1125318169-598002', + amount: -21.79, + currencyCode: 'EUR', + originalAmount: -21.79, + originalCurrency: 'EUR', + exchangeRate: 1.0, + merchantCity: 'PARIS ', + visibleTS: 1455292872000, + mcc: 5977, + mccGroup: 4, + merchantName: 'PANDORA CORP ', + merchantId: '6260861 ', + recurring: false, + userId: '93c3e18b-830a-4758-bb96-ef4d1d859fc3', + linkId: '1125318169-598002', + accountId: 'efe2cc9a-49da-4eea-bfa0-236eac673a8a', + category: 'micro-shopping', + cardId: '9d1e122f-76ea-4222-a059-a92348a40ac2', + pending: false, + transactionNature: 'NORMAL' + }]); + + return n26.transactions({}).then((me) => { + expect(me).to.be.eql([{ + id: 'bbd24eb7-925a-48dd-9c1e-75bb9f514d78', + type: 'AA', + smartLinkId: '1125318169-598002', + amount: -21.79, + currencyCode: 'EUR', + originalAmount: -21.79, + originalCurrency: 'EUR', + exchangeRate: 1.0, + merchantCity: 'PARIS ', + visibleTS: 1455292872000, + mcc: 5977, + mccGroup: 4, + merchantName: 'PANDORA CORP ', + merchantId: '6260861 ', + recurring: false, + userId: '93c3e18b-830a-4758-bb96-ef4d1d859fc3', + linkId: '1125318169-598002', + accountId: 'efe2cc9a-49da-4eea-bfa0-236eac673a8a', + category: 'micro-shopping', + cardId: '9d1e122f-76ea-4222-a059-a92348a40ac2', + pending: false, + transactionNature: 'NORMAL' + }]); + }); + }); + + it('should limit result', () => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/smrt/transactions') + .query({limit: 20, pending: false}) + .reply(200, [{ + id: 'bbd24eb7-925a-48dd-9c1e-75bb9f514d78', + type: 'AA', + smartLinkId: '1125318169-598002', + amount: -21.79, + currencyCode: 'EUR', + originalAmount: -21.79, + originalCurrency: 'EUR', + exchangeRate: 1.0, + merchantCity: 'PARIS ', + visibleTS: 1455292872000, + mcc: 5977, + mccGroup: 4, + merchantName: 'PANDORA CORP ', + merchantId: '6260861 ', + recurring: false, + userId: '93c3e18b-830a-4758-bb96-ef4d1d859fc3', + linkId: '1125318169-598002', + accountId: 'efe2cc9a-49da-4eea-bfa0-236eac673a8a', + category: 'micro-shopping', + cardId: '9d1e122f-76ea-4222-a059-a92348a40ac2', + pending: false, + transactionNature: 'NORMAL' + }]); + + return n26.transactions({limit: 20}); + }); + + it('should filter by categories result', () => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/smrt/transactions') + .query({limit: 50, categories: 'micro-education,micro-atm', pending: false}) + .reply(200, []); + + return n26.transactions({categories: ['micro-education', 'micro-atm']}); + }); + + it('should filter by date', () => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/smrt/transactions') + .query({limit: 50, from: 1454630400000, to: 1454803199999, pending: false}) + .reply(200, []); + + return n26.transactions({from: 1454630400000, to: 1454803199999}); + }); + + it('should filter by text', () => { + api = nock('https://api.tech26.de') + .defaultReplyHeaders({ + 'Content-Type': 'application/json' + }) + .matchHeader('Authorization', `Bearer ${data.access_token}`) + .get('/api/smrt/transactions') + .query({limit: 50, textFilter: 'loutre', pending: false}) + .reply(200, []); + + return n26.transactions({text: 'loutre'}); + }); + + afterEach((done) => { + done((!api.isDone()) ? new Error('Request not done') : null); + }); +}); diff --git a/tests/account/createTransfer.js b/tests/account/transfer.js similarity index 89% rename from tests/account/createTransfer.js rename to tests/account/transfer.js index 7bf50fe..a56beb8 100644 --- a/tests/account/createTransfer.js +++ b/tests/account/transfer.js @@ -18,7 +18,7 @@ beforeEach((done) => { }); }); -describe('createTransfer', () => { +describe('transfer', () => { describe('Success', () => { let api; @@ -71,7 +71,8 @@ describe('createTransfer', () => { delete transferData[param]; return n26.transfer(transferData).catch((err) => { - expect(err).to.be.equal('MISSING_PARAMS'); + expect(err).to.be.an.instanceOf(Error); + expect(err.message).to.equal('MISSING_PARAMS'); }); }); }); @@ -85,7 +86,8 @@ describe('createTransfer', () => { name: 'George Loutre', reference: require('crypto').randomBytes(256).toString('hex') }).catch((err) => { - expect(err).to.be.equal('REFERENCE_TOO_LONG'); + expect(err).to.be.an.instanceOf(Error); + expect(err.message).to.equal('REFERENCE_TOO_LONG'); }); }); }); diff --git a/tests/index.js b/tests/index.js index a0b4c45..58405ec 100644 --- a/tests/index.js +++ b/tests/index.js @@ -118,22 +118,22 @@ describe('Static', () => { }); describe('account', () => { + require('./account/account'); + require('./account/addresses'); require('./account/auth'); - require('./account/memo'); + require('./account/barzahlen'); + require('./account/cards'); require('./account/contacts'); - require('./account/createTransfer'); - require('./account/getAccount'); - require('./account/getAddresses'); - require('./account/getCards'); - require('./account/getMe'); - require('./account/getRecipients'); - require('./account/getTransactions'); - require('./account/getTransaction'); require('./account/invitations'); require('./account/limits'); - require('./account/unpair'); - require('./account/statuses'); - require('./account/barzahlen'); + require('./account/me'); + require('./account/memo'); + require('./account/recipients'); require('./account/statement'); require('./account/statements'); + require('./account/statuses'); + require('./account/transaction'); + require('./account/transactions'); + require('./account/transfer'); + require('./account/unpair'); }); diff --git a/tests/unmock.js b/tests/unmock.js index c3b3f61..3671857 100644 --- a/tests/unmock.js +++ b/tests/unmock.js @@ -233,7 +233,6 @@ describe('Create instance', function () { // eslint-disable-line func-names it('should check barzahlen', () => { return n26.barzahlen() .then((barzahlen) => { - barzahlenProperties.forEach(property => { expect(barzahlen).to.have.deep.property(property); }); @@ -393,7 +392,6 @@ describe('Create instance', function () { // eslint-disable-line func-names it('should return statuses', () => { return n26.statuses().then((statuses) => { - statusesProperties.forEach(property => { expect(statuses).to.have.deep.property(property); }); @@ -404,8 +402,6 @@ describe('Create instance', function () { // eslint-disable-line func-names it('should get account limits', () => { return n26.limits().then((limits) => { - console.log(limits) - console.log(`\tYour account is limited to ${limits[0].amount} for ${limits[0].limit}`); }); }); @@ -447,7 +443,6 @@ describe('Create instance', function () { // eslint-disable-line func-names it('should return statements', () => { return n26.statements().then((statements) => { - statements.forEach((statement) => { statementsProperties.forEach((property) => { expect(statement).to.have.deep.property(property); @@ -480,12 +475,12 @@ describe('Create instance', function () { // eslint-disable-line func-names }); }); - if (!process.env.INVITE ||!process.env.EMAIL) { + if (!process.env.INVITE || !process.env.EMAIL) { xit('shoud send invitation'); } else { it('should send invitation', () => { return n26.invitations(process.env.EMAIL).then(() => { - console.log(`\tInvitation sent`); + console.log('\tInvitation sent'); }); }); } @@ -525,7 +520,7 @@ describe('Create instance', function () { // eslint-disable-line func-names if (!process.env.UNPAIR || !process.env.CARD_NUMBER) { xit('should unpair phone'); } else { - it('should unpair phone', function (cb) { + it('should unpair phone', function (cb) { // eslint-disable-line func-names this.timeout(60000); return n26.unpairInit(process.env.TRANSFER_PIN, process.env.CARD_NUMBER) @@ -535,7 +530,7 @@ describe('Create instance', function () { // eslint-disable-line func-names return n26.unpairConfirm(smsNumber) .then(() => { - console.log(`\tDevice unpaired`); + console.log('\tDevice unpaired'); cb(); }) .catch(cb); From a9dfb21f62431233c7f1a9152feb4191582e3522 Mon Sep 17 00:00:00 2001 From: Pierrick Date: Sun, 12 Jun 2016 15:54:49 +0200 Subject: [PATCH 6/6] Bump to 1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c00e8ff..5ea884e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "number26", - "version": "1.0.0-rc.2", + "version": "1.0.0", "description": "Un-official node.js module for interact with your number26 account", "main": "index.js", "scripts": {