From e04cba2ba1d2670ebebbfcf85c869f3d456ea6a2 Mon Sep 17 00:00:00 2001 From: xendit-aw007 <86585384+xendit-aw007@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:01:14 +0700 Subject: [PATCH 1/2] feat: customer object v20201031 --- .gitignore | 1 + src/customer/customer.d.ts | 62 ++++++++++++++++++- src/customer/customer.js | 124 +++++++++++++++++++++++++++---------- 3 files changed, 155 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 4501341..e509dbf 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules/ coverage .vscode/ .idea +.tool-versions diff --git a/src/customer/customer.d.ts b/src/customer/customer.d.ts index 0eed4ad..4fb5f8b 100644 --- a/src/customer/customer.d.ts +++ b/src/customer/customer.d.ts @@ -10,6 +10,52 @@ interface Address { postalCode?: string; } +interface IdentityAccount { + type: string; + company?: string; + description?: string; + country?: string; + properties?: object; +} + +interface BusinessDetail { + businessName: string; + businessType?: string; + natureOfBusiness?: string; + businessDomicile?: string; + dateOfRegistration?: string; + tradingName?: string; +} + +interface Employment { + employerName?: string; + natureOfBusiness?: string; + roleDescription?: string; +} + +interface IndividualDetail { + givenNames: string; + givenNamesNonRoman?: string; + surname?: string; + surnameNonRoman?: string; + nationality?: string; + placeOfBirth?: string; + dateOfBirth?: Date; + gender?: string; + employment?: Employment; +} + +interface KYCDocument { + country: string; + type: string; + subType?: string; + documentName?: string; + documentNumber?: string; + expiresAt?: Date; + holderName?: string; + documentImages?: string[]; +} + export = class Customer { constructor({}); static _constructorWithInjectedXenditOpts: ( @@ -19,7 +65,7 @@ export = class Customer { referenceID: string; mobileNumber?: string; email?: string; - givenNames: string; + givenNames?: string; middleName?: string; surname?: string; description?: string; @@ -29,6 +75,20 @@ export = class Customer { dateOfBirth?: string; metadata?: object; apiVersion?: string; + type?: string; + individualDetail?: IndividualDetail; + businessDetail?: BusinessDetail; + phoneNumber?: string; + hashedPhoneNumber?: string; + identityAccounts?: IdentityAccount[]; + kycDocuments?: KYCDocument[]; + description?: string; + dateOfRegistration?: Date; + domicileOfRegistration?: string; + entity?: string; + client?: string; + clientName?: string; + metadata?: object; }): Promise; getCustomer(data: { id: string; apiVersion?: string }): Promise; getCustomerByReferenceID(data: { diff --git a/src/customer/customer.js b/src/customer/customer.js index 4351d34..169ede8 100644 --- a/src/customer/customer.js +++ b/src/customer/customer.js @@ -23,13 +23,7 @@ Customer._constructorWithInjectedXenditOpts = function(options) { Customer.prototype.createCustomer = function(data) { return promWithJsErr((resolve, reject) => { - const compulsoryFields = ['referenceID', 'givenNames']; - if (!data.mobileNumber) { - compulsoryFields.push('email'); - } - if (!data.email) { - compulsoryFields.push('mobileNumber'); - } + const compulsoryFields = populateCompulsaryFields(data, apiVersion); Validate.rejectOnMissingFields(compulsoryFields, data, reject); fetchWithHTTPErr(`${this.API_ENDPOINT}/customers`, { @@ -39,30 +33,7 @@ Customer.prototype.createCustomer = function(data) { Authorization: Auth.basicAuthHeader(this.opts.secretKey), 'API-VERSION': data.apiVersion ? data.apiVersion : '', }, - body: JSON.stringify({ - reference_id: data.referenceID, - mobile_number: data.mobileNumber, - email: data.email, - given_names: data.givenNames, - middle_name: data.middleName, - surname: data.surname, - description: data.description, - phone_number: data.phoneNumber, - nationality: data.nationality, - addresses: data.addresses - ? data.addresses.map(address => ({ - country: address.country, - street_line1: address.streetLine1, - street_line2: address.streetLine2, - city: address.city, - province: address.province, - state: address.state, - postal_code: address.postalCode, - })) - : [], - date_of_birth: data.dateOfBirth, - metadata: data.metadata, - }), + body: transformCustomerObjectBody(data, apiVersion), }) .then(resolve) .catch(reject); @@ -142,4 +113,95 @@ Customer.prototype.updateCustomer = function(data) { }); }; +function transformCustomerObjectBody(data, apiVersion) { + switch (apiVersion) { + case '2020-10-31': + return JSON.stringify({ + reference_id: data.referenceID, + type: data.type, + individual_detail: data.individualDetail, + business_detail: data.businessDetail, + mobile_number: data.mobileNumber, + phone_number: data.phoneNumber, + hashed_phone_number: data.hashedPhoneNumber, + email: data.email, + addresses: data.addresses + ? data.addresses.map(address => ({ + country: address.country, + street_line1: address.streetLine1, + street_line2: address.streetLine2, + city: address.city, + province: address.province, + state: address.state, + postal_code: address.postalCode, + })) + : [], + identity_accounts: data.identityAccounts + ? data.identity_accounts.map(identity_account => ({ + type: identity_account.type, + company: identity_account.company, + description: identity_account.description, + country: identity_account.country, + properties: identity_account.properties, + })) + : [], + kyc_documents: data.kycDocuments, + description: data.description, + date_of_registration: data.dateOfRegistration, + domicile_of_registration: data.domicileOfRegistration, + entity: data.entity, + client: data.client, + client_name: data.clientName, + metadata: data.metadata, + }); + case '2020-05-19': + default: + return JSON.stringify({ + reference_id: data.referenceID, + mobile_number: data.mobileNumber, + email: data.email, + given_names: data.givenNames, + middle_name: data.middleName, + surname: data.surname, + description: data.description, + phone_number: data.phoneNumber, + nationality: data.nationality, + addresses: data.addresses + ? data.addresses.map(address => ({ + country: address.country, + street_line1: address.streetLine1, + street_line2: address.streetLine2, + city: address.city, + province: address.province, + state: address.state, + postal_code: address.postalCode, + })) + : [], + date_of_birth: data.dateOfBirth, + metadata: data.metadata, + }); + } +} + +function populateCompulsaryFields(data, apiVersion) { + let compulsoryFields; + switch (apiVersion) { + case '2020-10-31': + compulsoryFields = ['referenceID', 'type']; + + return compulsoryFields; + case '2020-05-19': + default: + compulsoryFields = ['referenceID', 'givenNames']; + if (!data.mobileNumber) { + compulsoryFields.push('email'); + } + if (!data.email) { + compulsoryFields.push('mobileNumber'); + } + + return compulsoryFields; + } +} + module.exports = Customer; From ae8ddf6be2f5f1c328237284761c381a51b60a16 Mon Sep 17 00:00:00 2001 From: xendit-aw007 <86585384+xendit-aw007@users.noreply.github.com> Date: Mon, 7 Aug 2023 17:38:33 +0700 Subject: [PATCH 2/2] test: customer object v20201031 --- examples/with_async/customer.js | 36 ++++ examples/with_promises/customer.js | 37 ++++ ...mer.test.js => customer_v20200519.test.js} | 0 integration_test/customer_v20201031.test.js | 37 ++++ integration_test/index.js | 3 +- src/customer/customer.d.ts | 13 ++ src/customer/customer.js | 79 ++++---- test/customer/constants.js | 92 +++++++++- ...omer.test.js => customerv20200519.test.js} | 25 ++- test/customer/customerv20201031.test.js | 169 ++++++++++++++++++ 10 files changed, 445 insertions(+), 46 deletions(-) rename integration_test/{customer.test.js => customer_v20200519.test.js} (100%) create mode 100644 integration_test/customer_v20201031.test.js rename test/customer/{customer.test.js => customerv20200519.test.js} (86%) create mode 100644 test/customer/customerv20201031.test.js diff --git a/examples/with_async/customer.js b/examples/with_async/customer.js index 085e914..2f46475 100644 --- a/examples/with_async/customer.js +++ b/examples/with_async/customer.js @@ -36,3 +36,39 @@ const c = new Customer({}); process.exit(1); } })(); + +(async function() { + try { + let customer = await c.createCustomer({ + referenceID: new Date().toISOString(), + type: 'INDIVIDUAL', + individualDetail: { + givenNames: 'customer 1', + surname: 'surname', + }, + email: 'customer@website.com', + mobileNumber: '+6281212345678', + description: 'dummy customer', + addresses: [], + apiVersion: '2020-10-31', + }); + console.log('created customer', customer); // eslint-disable-line no-console + + customer = await c.getCustomer({ + id: customer.id, + apiVersion: '2020-10-31', + }); + // eslint-disable-next-line no-console + console.log('retrieved customer', customer); + + const customers = await c.getCustomerByReferenceID({ + referenceID: customer.reference_id, + apiVersion: '2020-10-31', + }); + // eslint-disable-next-line no-console + console.log('retrieved customers', customers); + } catch (e) { + console.error(e); // eslint-disable-line no-console + process.exit(1); + } +})(); diff --git a/examples/with_promises/customer.js b/examples/with_promises/customer.js index 928dbc3..d73361f 100644 --- a/examples/with_promises/customer.js +++ b/examples/with_promises/customer.js @@ -37,3 +37,40 @@ c.createCustomer({ console.error(e); // eslint-disable-line no-console process.exit(1); }); + +c.createCustomer({ + referenceID: new Date().toISOString(), + type: 'INDIVIDUAL', + individualDetail: { + givenNames: 'customer 1', + surname: 'surname', + }, + email: 'customer@website.com', + mobileNumber: '+6281212345678', + description: 'dummy customer', + addresses: [], + apiVersion: '2020-10-31', +}) + .then(r => { + console.log('created customer', r); // eslint-disable-line no-console + return r; + }) + .then(r => c.getCustomer({ id: r.id, apiVersion: '2020-10-31' })) + .then(r => { + console.log('retrieved customer', r); // eslint-disable-line no-console + return r; + }) + .then(r => + c.getCustomerByReferenceID({ + referenceID: r.reference_id, + apiVersion: '2020-10-31', + }), + ) + .then(r => { + console.log('retrieved customers', r); // eslint-disable-line no-console + return r[0]; + }) + .catch(e => { + console.error(e); // eslint-disable-line no-console + process.exit(1); + }); diff --git a/integration_test/customer.test.js b/integration_test/customer_v20200519.test.js similarity index 100% rename from integration_test/customer.test.js rename to integration_test/customer_v20200519.test.js diff --git a/integration_test/customer_v20201031.test.js b/integration_test/customer_v20201031.test.js new file mode 100644 index 0000000..dd68976 --- /dev/null +++ b/integration_test/customer_v20201031.test.js @@ -0,0 +1,37 @@ +const x = require('./xendit.test'); + +const { Customer } = x; +const c = new Customer({}); + +module.exports = function() { + return c + .createCustomer({ + referenceID: new Date().toISOString(), + type: 'INDIVIDUAL', + individualDetail: { + givenNames: 'customer 1', + surname: 'surname', + }, + email: 'customer@website.com', + mobileNumber: '+6281212345678', + description: 'dummy customer', + addresses: [], + apiVersion: '2020-10-31', + }) + .then(r => c.getCustomer({ id: r.id, apiVersion: '2020-10-31' })) + .then(r => + c.getCustomerByReferenceID({ + referenceID: r.reference_id, + apiVersion: '2020-10-31', + }), + ) + .then(() => { + // eslint-disable-next-line no-console + console.log('Customer integration test done...'); + }) + .catch(e => { + throw new Error( + `Customer integration tests failed with error: ${e.message}`, + ); + }); +}; diff --git a/integration_test/index.js b/integration_test/index.js index d5379e4..6ac44bb 100644 --- a/integration_test/index.js +++ b/integration_test/index.js @@ -12,7 +12,8 @@ Promise.all([ require('./qr_code.test')(), require('./platform.test')(), require('./regional_retail_outlet.test'), - require('./customer.test')(), + require('./customer_v20200519.test')(), + require('./customer_v20201031.test')(), require('./direct_debit.test')(), require('./report.test')(), require('./transaction.test')(), diff --git a/src/customer/customer.d.ts b/src/customer/customer.d.ts index 4fb5f8b..db72929 100644 --- a/src/customer/customer.d.ts +++ b/src/customer/customer.d.ts @@ -109,5 +109,18 @@ export = class Customer { dateOfBirth?: string; metadata?: object; apiVersion?: string; + type?: string; + individualDetail?: IndividualDetail; + businessDetail?: BusinessDetail; + phoneNumber?: string; + hashedPhoneNumber?: string; + identityAccounts?: IdentityAccount[]; + kycDocuments?: KYCDocument[]; + description?: string; + dateOfRegistration?: Date; + domicileOfRegistration?: string; + entity?: string; + client?: string; + clientName?: string; }): Promise; }; diff --git a/src/customer/customer.js b/src/customer/customer.js index 169ede8..b728039 100644 --- a/src/customer/customer.js +++ b/src/customer/customer.js @@ -23,6 +23,7 @@ Customer._constructorWithInjectedXenditOpts = function(options) { Customer.prototype.createCustomer = function(data) { return promWithJsErr((resolve, reject) => { + const apiVersion = data.apiVersion ? data.apiVersion : ''; const compulsoryFields = populateCompulsaryFields(data, apiVersion); Validate.rejectOnMissingFields(compulsoryFields, data, reject); @@ -31,7 +32,7 @@ Customer.prototype.createCustomer = function(data) { headers: { 'Content-Type': 'application/json', Authorization: Auth.basicAuthHeader(this.opts.secretKey), - 'API-VERSION': data.apiVersion ? data.apiVersion : '', + 'API-VERSION': apiVersion, }, body: transformCustomerObjectBody(data, apiVersion), }) @@ -76,6 +77,7 @@ Customer.prototype.getCustomerByReferenceID = function(data) { }; Customer.prototype.updateCustomer = function(data) { + const apiVersion = data.apiVersion ? data.apiVersion : ''; return promWithJsErr((resolve, reject) => { fetchWithHTTPErr(`${this.API_ENDPOINT}/customers/${data.id}`, { method: 'PATCH', @@ -84,29 +86,7 @@ Customer.prototype.updateCustomer = function(data) { Authorization: Auth.basicAuthHeader(this.opts.secretKey), 'API-VERSION': data.apiVersion ? data.apiVersion : '', }, - body: JSON.stringify({ - reference_id: data.referenceID, - mobile_number: data.mobileNumber, - given_names: data.givenNames, - middle_name: data.middleName, - surname: data.surname, - description: data.description, - phone_number: data.phoneNumber, - nationality: data.nationality, - addresses: data.addresses - ? data.addresses.map(address => ({ - country: address.country, - street_line1: address.streetLine1, - street_line2: address.streetLine2, - city: address.city, - province: address.province, - state: address.state, - postal_code: address.postalCode, - })) - : [], - date_of_birth: data.dateOfBirth, - metadata: data.metadata, - }), + body: transformCustomerObjectBody(data, apiVersion), }) .then(resolve) .catch(reject); @@ -119,8 +99,36 @@ function transformCustomerObjectBody(data, apiVersion) { return JSON.stringify({ reference_id: data.referenceID, type: data.type, - individual_detail: data.individualDetail, - business_detail: data.businessDetail, + individual_detail: data.individualDetail + ? { + given_names: data.individualDetail.givenNames, + surname: data.individualDetail.surname, + nationality: data.individualDetail.nationality, + place_of_birth: data.individualDetail.placeOfBirth, + date_of_birth: data.individualDetail.dateOfBirth, + gender: data.individualDetail.gender, + employment: data.individualDetail.employment + ? { + employer_name: + data.individualDetail.employment.employerName, + nature_of_business: + data.individualDetail.employment.natureOfBusiness, + role_description: + data.individualDetail.employment.roleDescription, + } + : undefined, + } + : undefined, + business_detail: data.businessDetail + ? { + business_name: data.businessDetail.businessName, + trading_name: data.businessDetail.tradingName, + business_type: data.businessDetail.businessType, + nature_of_business: data.businessDetail.natureOfBusiness, + business_domicile: data.businessDetail.businessDomicile, + date_of_registration: data.businessDetail.dateOfRegistration, + } + : undefined, mobile_number: data.mobileNumber, phone_number: data.phoneNumber, hashed_phone_number: data.hashedPhoneNumber, @@ -135,17 +143,28 @@ function transformCustomerObjectBody(data, apiVersion) { state: address.state, postal_code: address.postalCode, })) - : [], + : undefined, identity_accounts: data.identityAccounts - ? data.identity_accounts.map(identity_account => ({ + ? data.identityAccounts.map(identity_account => ({ type: identity_account.type, company: identity_account.company, description: identity_account.description, country: identity_account.country, properties: identity_account.properties, })) - : [], - kyc_documents: data.kycDocuments, + : undefined, + kyc_documents: data.kycDocuments + ? data.kycDocuments.map(kycDocument => ({ + country: kycDocument.country, + type: kycDocument.type, + sub_type: kycDocument.subType, + document_name: kycDocument.documentName, + document_number: kycDocument.documentNumber, + expires_at: kycDocument.expiresAt, + holder_name: kycDocument.holderName, + document_images: kycDocument.documentImages, + })) + : undefined, description: data.description, date_of_registration: data.dateOfRegistration, domicile_of_registration: data.domicileOfRegistration, diff --git a/test/customer/constants.js b/test/customer/constants.js index 41ff3de..de446bd 100644 --- a/test/customer/constants.js +++ b/test/customer/constants.js @@ -5,7 +5,7 @@ const EMAIL = 'customer@website.com'; const MOBILE_NUMBER = '+6281212345678'; const MIDDLE_NAME = 'middle'; const SURNAME = 'surname'; -const VALID_CREATE_CUSTOMER_RESPONSE = { +const VALID_CREATE_CUSTOMER_RESPONSE_V20200519 = { id: CUSTOMER_ID, reference_id: REFERENCE_ID, given_names: GIVEN_NAMES, @@ -22,7 +22,7 @@ const VALID_CREATE_CUSTOMER_RESPONSE = { addresses: null, source_of_wealth: null, }; -const VALID_CUSTOMER = { +const VALID_CUSTOMER_V20200519 = { id: CUSTOMER_ID, reference_id: REFERENCE_ID, given_names: GIVEN_NAMES, @@ -74,7 +74,84 @@ const VALID_CUSTOMER = { ], source_of_wealth: null, }; -const VALID_CUSTOMER_ARRAY = [VALID_CUSTOMER, VALID_CUSTOMER]; +const VALID_CUSTOMER_ARRAY_V20200519 = [ + VALID_CUSTOMER_V20200519, + VALID_CUSTOMER_V20200519, +]; + +const VALID_CREATE_CUSTOMER_RESPONSE_V20201031 = { + id: 'cust-' + CUSTOMER_ID, + reference_id: REFERENCE_ID, + type: 'INDIVIDUAL', + individual_detail: { + given_names: GIVEN_NAMES, + middle_name: MIDDLE_NAME, + surname: SURNAME, + date_of_birth: null, + employment: null, + nationality: null, + }, + email: EMAIL, + mobile_number: MOBILE_NUMBER, + description: 'dummy customer', + phone_number: null, + metadata: null, + addresses: null, +}; + +const VALID_CUSTOMER_V20201031 = { + id: CUSTOMER_ID, + reference_id: REFERENCE_ID, + given_names: GIVEN_NAMES, + type: 'INDIVIDUAL', + individual_detail: { + given_names: GIVEN_NAMES, + middle_name: MIDDLE_NAME, + surname: SURNAME, + date_of_birth: null, + employment: null, + nationality: null, + }, + email: EMAIL, + mobile_number: MOBILE_NUMBER, + description: 'dummy customer', + phone_number: null, + metadata: null, + addresses: [ + { + address_id: '9b28de5e-57b2-4072-896a-72995a5802cd', + street_line1: 'Panglima Polim IV', + street_line2: 'Ruko Grand Panglima Polim, Blok E', + city: 'Jakarta Selatan', + province_state: 'DKI Jakarta', + postal_code: '993448', + country: 'ID', + category: 'HOME', + is_primary: true, + created: '2021-02-01T06:35:13.536Z', + status: 'ACTIVE', + updated: '2021-02-01T06:35:13.536Z', + }, + { + address_id: '95a9346b-adae-4dd1-aeaf-1a961eda2cb2', + street_line1: 'Panglima Polim V', + street_line2: 'Ruko Grand Panglima Polim, Blok F', + city: 'Jakarta Selatan', + province_state: 'DKI Jakarta', + postal_code: '993448', + category: 'WORK', + country: 'ID', + status: 'ACTIVE', + updated: '2021-02-01T06:35:13.536Z', + }, + ], + source_of_wealth: null, +}; + +const VALID_CUSTOMER_ARRAY_V20201031 = [ + VALID_CUSTOMER_V20201031, + VALID_CUSTOMER_V20201031, +]; module.exports = { CUSTOMER_ID, @@ -84,7 +161,10 @@ module.exports = { MOBILE_NUMBER, MIDDLE_NAME, SURNAME, - VALID_CREATE_CUSTOMER_RESPONSE, - VALID_CUSTOMER, - VALID_CUSTOMER_ARRAY, + VALID_CREATE_CUSTOMER_RESPONSE_V20200519, + VALID_CREATE_CUSTOMER_RESPONSE_V20201031, + VALID_CUSTOMER_V20200519, + VALID_CUSTOMER_ARRAY_V20200519, + VALID_CUSTOMER_V20201031, + VALID_CUSTOMER_ARRAY_V20201031, }; diff --git a/test/customer/customer.test.js b/test/customer/customerv20200519.test.js similarity index 86% rename from test/customer/customer.test.js rename to test/customer/customerv20200519.test.js index 95f13a1..1f09579 100644 --- a/test/customer/customer.test.js +++ b/test/customer/customerv20200519.test.js @@ -29,10 +29,10 @@ before(function() { surname: TestConstants.SURNAME, addresses: [], }) - .reply(200, TestConstants.VALID_CREATE_CUSTOMER_RESPONSE); + .reply(200, TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20200519); nock(customer.API_ENDPOINT) .get(`/customers/${TestConstants.CUSTOMER_ID}`) - .reply(200, TestConstants.VALID_CREATE_CUSTOMER_RESPONSE); + .reply(200, TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20200519); nock(customer.API_ENDPOINT) .patch(`/customers/${TestConstants.CUSTOMER_ID}`, { description: 'customer dummy', @@ -52,13 +52,16 @@ before(function() { }, ], }) - .reply(200, TestConstants.VALID_CUSTOMER); + .reply(200, TestConstants.VALID_CUSTOMER_V20200519); nock(customer.API_ENDPOINT) .get(`/customers?reference_id=${TestConstants.REFERENCE_ID}`) - .reply(200, TestConstants.VALID_CUSTOMER_ARRAY); + .reply(200, TestConstants.VALID_CUSTOMER_ARRAY_V20200519); +}); +after(function() { + nock.cleanAll(); }); -describe('Customer Service', function() { +describe('Customer Service v2020-05-19', function() { describe('createCustomer', () => { it('should create a customer', done => { expect( @@ -73,7 +76,9 @@ describe('Customer Service', function() { addresses: [], }), ) - .to.eventually.deep.equal(TestConstants.VALID_CREATE_CUSTOMER_RESPONSE) + .to.eventually.deep.equal( + TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20200519, + ) .and.notify(done); }); it('should report missing required fields', done => { @@ -92,7 +97,9 @@ describe('Customer Service', function() { describe('getCustomer', () => { it('should get a customer', done => { expect(customer.getCustomer({ id: TestConstants.CUSTOMER_ID })) - .to.eventually.deep.equal(TestConstants.VALID_CREATE_CUSTOMER_RESPONSE) + .to.eventually.deep.equal( + TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20200519, + ) .and.notify(done); }); it('should report missing required fields', done => { @@ -131,7 +138,7 @@ describe('Customer Service', function() { ], }), ) - .to.eventually.deep.equal(TestConstants.VALID_CUSTOMER) + .to.eventually.deep.equal(TestConstants.VALID_CUSTOMER_V20200519) .and.notify(done); }); }); @@ -143,7 +150,7 @@ describe('Customer Service', function() { referenceID: TestConstants.REFERENCE_ID, }), ) - .to.eventually.deep.equal(TestConstants.VALID_CUSTOMER_ARRAY) + .to.eventually.deep.equal(TestConstants.VALID_CUSTOMER_ARRAY_V20200519) .and.notify(done); }); it('should report missing required fields', done => { diff --git a/test/customer/customerv20201031.test.js b/test/customer/customerv20201031.test.js new file mode 100644 index 0000000..eb24ea6 --- /dev/null +++ b/test/customer/customerv20201031.test.js @@ -0,0 +1,169 @@ +const chai = require('chai'); +const chaiAsProm = require('chai-as-promised'); +const TestConstants = require('./constants'); +const { expect } = chai; +const nock = require('nock'); +const { Errors } = require('../../src/xendit'); +const Xendit = require('../../src/xendit'); + +const x = new Xendit({ + secretKey: 'fake_secret_key', +}); + +chai.use(chaiAsProm); + +const { Customer } = x; +let customer = new Customer({}); +const apiVersion = '2020-10-31'; +beforeEach(function() { + customer = new Customer({}); +}); +before(function() { + nock(customer.API_ENDPOINT) + .post('/customers', { + reference_id: TestConstants.REFERENCE_ID, + type: 'INDIVIDUAL', + individual_detail: { + given_names: TestConstants.GIVEN_NAMES, + surname: TestConstants.SURNAME, + }, + email: TestConstants.EMAIL, + mobile_number: TestConstants.MOBILE_NUMBER, + description: 'dummy customer', + }) + .reply(200, TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20201031); + nock(customer.API_ENDPOINT) + .get(`/customers/${'cust-' + TestConstants.CUSTOMER_ID}`) + .reply(200, TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20201031); + nock(customer.API_ENDPOINT) + .patch(`/customers/${'cust-' + TestConstants.CUSTOMER_ID}`, { + addresses: [ + { + country: 'ID', + city: 'Jakarta', + }, + { + country: 'ID', + city: 'Jakarta', + }, + ], + description: 'dummy customer', + }) + .reply(200, TestConstants.VALID_CUSTOMER_V20201031); + nock(customer.API_ENDPOINT) + .get(`/customers?reference_id=${'ref-' + TestConstants.REFERENCE_ID}`) + .reply(200, TestConstants.VALID_CUSTOMER_ARRAY_V20201031); +}); + +after(function() { + nock.cleanAll(); +}); + +describe('Customer Service v2020-10-31', function() { + describe('createCustomer', () => { + it('should create a customer', done => { + expect( + customer.createCustomer({ + referenceID: TestConstants.REFERENCE_ID, + type: 'INDIVIDUAL', + individualDetail: { + givenNames: TestConstants.GIVEN_NAMES, + surname: TestConstants.SURNAME, + }, + email: TestConstants.EMAIL, + mobileNumber: TestConstants.MOBILE_NUMBER, + description: 'dummy customer', + apiVersion: apiVersion, + }), + ) + .to.eventually.deep.equal( + TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20201031, + ) + .and.notify(done); + }); + it('should report missing required fields', done => { + expect(customer.createCustomer({})) + .to.eventually.to.be.rejected.then(e => + Promise.all([ + expect(e).to.have.property('status', 400), + expect(e).to.have.property('code', Errors.API_VALIDATION_ERROR), + ]), + ) + .then(() => done()) + .catch(e => done(e)); + }); + }); + + describe('getCustomer', () => { + it('should get a customer', done => { + expect( + customer.getCustomer( + { id: 'cust-' + TestConstants.CUSTOMER_ID }, + apiVersion, + ), + ) + .to.eventually.deep.equal( + TestConstants.VALID_CREATE_CUSTOMER_RESPONSE_V20201031, + ) + .and.notify(done); + }); + it('should report missing required fields', done => { + expect(customer.getCustomer({}, apiVersion)) + .to.eventually.to.be.rejected.then(e => + Promise.all([ + expect(e).to.have.property('status', 400), + expect(e).to.have.property('code', Errors.API_VALIDATION_ERROR), + ]), + ) + .then(() => done()) + .catch(e => done(e)); + }); + }); + + describe('updateCustomer', () => { + it('should update a customer', done => { + expect( + customer.updateCustomer({ + id: 'cust-' + TestConstants.CUSTOMER_ID, + addresses: [ + { + country: 'ID', + city: 'Jakarta', + }, + { + country: 'ID', + city: 'Jakarta', + }, + ], + description: 'dummy customer', + apiVersion: apiVersion, + }), + ) + .to.eventually.deep.equal(TestConstants.VALID_CUSTOMER_V20201031) + .and.notify(done); + }); + }); + + describe('getCustomerByReferenceID', () => { + it('should get customers by reference ID', done => { + expect( + customer.getCustomerByReferenceID({ + referenceID: 'ref-' + TestConstants.REFERENCE_ID, + }), + ) + .to.eventually.deep.equal(TestConstants.VALID_CUSTOMER_ARRAY_V20201031) + .and.notify(done); + }); + it('should report missing required fields', done => { + expect(customer.getCustomerByReferenceID({})) + .to.eventually.to.be.rejected.then(e => + Promise.all([ + expect(e).to.have.property('status', 400), + expect(e).to.have.property('code', Errors.API_VALIDATION_ERROR), + ]), + ) + .then(() => done()) + .catch(e => done(e)); + }); + }); +});