diff --git a/src/resources/Account/index.ts b/src/resources/Account/index.ts index d3dc1bd..696e990 100644 --- a/src/resources/Account/index.ts +++ b/src/resources/Account/index.ts @@ -100,7 +100,7 @@ export class Account extends Resource { */ async create(data: IACHCreateOpts | ILiabilityCreateOpts, requestConfig?: IRequestConfig) { - return super._create, IACHCreateOpts | ILiabilityCreateOpts>(data, requestConfig); + return super._create, IACHCreateOpts | ILiabilityCreateOpts>(data, undefined, requestConfig); } diff --git a/src/resources/Entity/ManualConnect.ts b/src/resources/Entity/ManualConnect.ts index 732262c..88795aa 100644 --- a/src/resources/Entity/ManualConnect.ts +++ b/src/resources/Entity/ManualConnect.ts @@ -44,6 +44,6 @@ export default class EntityManualConnect extends Resource { } async create(opts: IManualConnectCreateOpts, requestConfig?: IRequestConfig) { - return super._create, IManualConnectCreateOpts>(opts, requestConfig); + return super._create, IManualConnectCreateOpts>(opts, undefined, requestConfig); } }; diff --git a/src/resources/Entity/Subscriptions.ts b/src/resources/Entity/Subscriptions.ts index 0f6e7b1..758dd85 100644 --- a/src/resources/Entity/Subscriptions.ts +++ b/src/resources/Entity/Subscriptions.ts @@ -52,7 +52,7 @@ export default class EntitySubscriptions extends Resource { enroll: opts as TEntitySubscriptionNames, }; } - return super._create, IEntitySubscriptionCreateOpts>(opts, requestConfig); + return super._create, IEntitySubscriptionCreateOpts>(opts, undefined, requestConfig); } /** diff --git a/src/resources/Entity/index.ts b/src/resources/Entity/index.ts index d06fe59..8ea2578 100644 --- a/src/resources/Entity/index.ts +++ b/src/resources/Entity/index.ts @@ -100,6 +100,7 @@ export class Entity extends Resource { ) { return super._create, IIndividualCreateOpts | ICorporationCreateOpts>( opts, + undefined, requestConfig, ); } diff --git a/src/resources/ForwardingRequest/index.ts b/src/resources/ForwardingRequest/index.ts index b979181..42b5b8c 100644 --- a/src/resources/ForwardingRequest/index.ts +++ b/src/resources/ForwardingRequest/index.ts @@ -61,6 +61,6 @@ export default class ForwardingRequest extends Resource { } async create(opts: IForwardingRequestCreateOpts, requestConfig?: IRequestConfig) { - return super._create, IForwardingRequestCreateOpts>(opts, requestConfig); + return super._create, IForwardingRequestCreateOpts>(opts, undefined, requestConfig); } }; diff --git a/src/resources/Payment/index.ts b/src/resources/Payment/index.ts index a5ebcc8..d29fab6 100644 --- a/src/resources/Payment/index.ts +++ b/src/resources/Payment/index.ts @@ -62,7 +62,7 @@ export class Payment extends Resource { */ async create(opts: IPaymentCreateOpts, requestConfig?: IRequestConfig) { - return super._create, IPaymentCreateOpts>(opts, requestConfig); + return super._create, IPaymentCreateOpts>(opts, undefined, requestConfig); } /** diff --git a/src/resources/Report/index.ts b/src/resources/Report/index.ts index f83ae8a..4d765cc 100644 --- a/src/resources/Report/index.ts +++ b/src/resources/Report/index.ts @@ -68,7 +68,7 @@ export default class Report extends Resource { */ async create(opts: IReportCreateOpts, requestConfig?: IRequestConfig) { - return super._create, IReportCreateOpts>(opts, requestConfig); + return super._create, IReportCreateOpts>(opts, undefined, requestConfig); } /** diff --git a/src/resources/Secret/index.ts b/src/resources/Secret/index.ts index 968168a..6ea417e 100644 --- a/src/resources/Secret/index.ts +++ b/src/resources/Secret/index.ts @@ -35,7 +35,7 @@ export default class Secret extends Resource { } async create(opts: ISecretCreateOpts, requestConfig?: IRequestConfig) { - return super._create, ISecretCreateOpts>(opts, requestConfig); + return super._create, ISecretCreateOpts>(opts, undefined, requestConfig); } async delete(sec_id: string) { diff --git a/src/resources/Team/index.ts b/src/resources/Team/index.ts index 6fefa34..79b9e61 100644 --- a/src/resources/Team/index.ts +++ b/src/resources/Team/index.ts @@ -71,7 +71,7 @@ export class TeamPublicKeys extends Resource { } async create(opts: IMLEPublicKeyCreateOpts, requestConfig?: IRequestConfig) { - return super._create, IMLEPublicKeyCreateOpts>(opts, requestConfig); + return super._create, IMLEPublicKeyCreateOpts>(opts, undefined, requestConfig); } async delete(key_id: string) { @@ -92,7 +92,7 @@ export default class Team extends Resource { } async create(opts: ITeamCreateOpts, requestConfig?: IRequestConfig) { - return super._create, ITeamCreateOpts>(opts, requestConfig); + return super._create, ITeamCreateOpts>(opts, undefined, requestConfig); } async updateEncryptionKey(opts: ITeamEncryptionKeyOpts, requestConfig?: IRequestConfig) { diff --git a/src/resources/Webhook/index.ts b/src/resources/Webhook/index.ts index c79319b..1c2a5ea 100644 --- a/src/resources/Webhook/index.ts +++ b/src/resources/Webhook/index.ts @@ -38,7 +38,7 @@ export default class Webhook extends Resource { */ async create(opts: IWebhookCreateOpts, requestConfig?: IRequestConfig) { - return super._create, IWebhookCreateOpts>(opts, requestConfig); + return super._create, IWebhookCreateOpts>(opts, undefined, requestConfig); } /** diff --git a/test/index.ts b/test/index.ts index 3bef1b7..ec5f8a5 100644 --- a/test/index.ts +++ b/test/index.ts @@ -11,3 +11,4 @@ require('./resources/HealthCheck.tests'); require('./resources/Metadata.tests'); require('./resources/Event.tests'); require('./resources/Opal.tests'); +require('./resources/RequestConfig.tests'); diff --git a/test/resources/RequestConfig.tests.ts b/test/resources/RequestConfig.tests.ts new file mode 100644 index 0000000..abafdc4 --- /dev/null +++ b/test/resources/RequestConfig.tests.ts @@ -0,0 +1,175 @@ +import { should } from 'chai'; +import { + after, before, beforeEach, describe, it, +} from 'mocha'; +import * as http from 'http'; +import type { AddressInfo } from 'net'; +import { Method } from '../../src/method'; +import type { IRequestConfig } from '../../src/resource'; + +should(); + +interface ICapturedRequest { + url: string; + headers: http.IncomingHttpHeaders; +}; + +interface ICreateUnderTest { + name: string; + create: (requestConfig?: IRequestConfig) => Promise; +}; + +const idempotency_key = 'test-idempotency-key'; + +describe('Request config - core methods tests', () => { + let server: http.Server; + let client: Method; + let requests: ICapturedRequest[] = []; + + before((done) => { + server = http.createServer((req, res) => { + requests.push({ url: req.url || '', headers: req.headers }); + res.setHeader('content-type', 'application/json'); + res.end(JSON.stringify({ data: {} })); + }); + + server.listen(0, '127.0.0.1', () => { + const { port } = server.address() as AddressInfo; + + client = new Method({ + apiKey: 'sk_test', + env: 'dev', + baseURL: `http://127.0.0.1:${port}`, + }); + + done(); + }); + }); + + after((done) => { + server.close(() => done()); + }); + + beforeEach(() => { + requests = []; + }); + + const creates: ICreateUnderTest[] = [ + { + name: 'accounts.create', + create: (requestConfig?: IRequestConfig) => client.accounts.create({ + holder_id: 'ent_au22adjEjWQpF', + ach: { routing: '367537407', number: '57838927', type: 'checking' }, + }, requestConfig), + }, + { + name: 'entities.create', + create: (requestConfig?: IRequestConfig) => client.entities.create({ + type: 'individual', + individual: { first_name: 'Kevin', last_name: 'Doyle' }, + }, requestConfig), + }, + { + name: 'entities.subscriptions.create', + create: (requestConfig?: IRequestConfig) => client + .entities('ent_au22adjEjWQpF') + .subscriptions + .create({ enroll: 'credit_score' }, requestConfig), + }, + { + name: 'entities.manualConnect.create', + create: (requestConfig?: IRequestConfig) => client + .entities('ent_au22adjEjWQpF') + .manualConnect + .create({ bureau: 'equifax', tradelines: [] }, requestConfig), + }, + { + name: 'payments.create', + create: (requestConfig?: IRequestConfig) => client.payments.create({ + amount: 5000, + source: 'acc_JMJZTrpu3vAmA', + destination: 'acc_AXthEBs9NPbfa', + description: 'Loan Pmt', + }, requestConfig), + }, + { + name: 'reports.create', + create: (requestConfig?: IRequestConfig) => client.reports.create({ + type: 'payments.created.current', + }, requestConfig), + }, + { + name: 'secrets.create', + create: (requestConfig?: IRequestConfig) => client.secrets.create({ + value: 'test-secret-value', + }, requestConfig), + }, + { + name: 'forwardingRequests.create', + create: (requestConfig?: IRequestConfig) => client.forwardingRequests.create({ + url: 'https://api.example.app/forward', + method: 'POST', + headers: {}, + body: '{}', + bindings: {}, + }, requestConfig), + }, + { + name: 'webhooks.create', + create: (requestConfig?: IRequestConfig) => client.webhooks.create({ + type: 'payment.create', + url: 'https://api.example.app/webhook', + }, requestConfig), + }, + { + name: 'teams.create', + create: (requestConfig?: IRequestConfig) => client.teams.create({ + name: 'Test Team', + }, requestConfig), + }, + { + name: 'teams.publicKeys.create', + create: (requestConfig?: IRequestConfig) => client.teams.publicKeys.create({ + jwk: { kty: 'RSA' }, + }, requestConfig), + }, + ]; + + creates.forEach((resource) => { + describe(resource.name, () => { + it('should send the idempotency key as an Idempotency-Key header.', async () => { + await resource.create({ idempotency_key }); + + requests.should.have.length(1); + requests[0].headers.should.have.property('idempotency-key', idempotency_key); + }); + + it('should not send the idempotency key as a query parameter.', async () => { + await resource.create({ idempotency_key }); + + requests.should.have.length(1); + requests[0].url.should.not.contain('idempotency_key'); + }); + + it('should not send an Idempotency-Key header when no request config is given.', async () => { + await resource.create(); + + requests.should.have.length(1); + requests[0].headers.should.not.have.property('idempotency-key'); + }); + }); + }); + + describe('entities.connect.create', () => { + it('should send the Idempotency-Key header alongside its query parameters.', async () => { + await client + .entities('ent_au22adjEjWQpF') + .connect + .create({}, { expand: ['accounts'] }, { idempotency_key }); + + requests.should.have.length(1); + requests[0].headers.should.have.property('idempotency-key', idempotency_key); + requests[0].url.should.contain('expand'); + }); + }); +});