Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions src/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,18 @@ export default class Resource extends ExtensibleFunction {
return (await this.client.get('', { params })).data.data;
}

protected async _create<Response, Data>(
protected async _create<Response, Data, Params = {}>(
data: Data,
params?: Params,
requestConfig: IRequestConfig = {},
): Promise<Response> {
const _requestConfig = { headers: {} };
if (requestConfig.idempotency_key) {
_requestConfig.headers = {
'Idempotency-Key': requestConfig.idempotency_key,
};
}
const _requestConfig = {
headers: requestConfig.idempotency_key
? { 'Idempotency-Key': requestConfig.idempotency_key }
: {},
params,
};

return (await this.client.post('', data, _requestConfig)).data.data;
}

Expand Down
5 changes: 3 additions & 2 deletions src/resources/Account/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ export interface IAccountBalance {
};

export interface IAccountCardBrandInfo {
art_id: string;
id: string;
art_id?: string;
url: string;
name: string;
};
Expand All @@ -311,7 +312,7 @@ export interface IAccountCardBrand {
issuer: string | null;
last4: string | null;
brands: IAccountCardBrandInfo[];
status: 'completed' | 'failed';
status: 'in_progress' | 'completed' | 'failed';
shared: boolean;
source: 'method' | 'network' | null;
error: IResourceError | null;
Expand Down
54 changes: 49 additions & 5 deletions src/resources/Entity/Connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,50 @@ import Resource, { IResourceListOpts } from '../../resource';
import Configuration, { IResponse } from '../../configuration';
import type { IEntityConnect } from './types';

export const AccountExpandableFields = {
sensitive: 'sensitive',
balance: 'balance',
card_brand: 'card_brand',
attribute: 'attribute',
payoff: 'payoff',
transaction: 'transaction',
update: 'update',
payment_instrument: 'payment_instrument',
latest_verification_session: 'latest_verification_session',
} as const;

type AccountExpandableField = typeof AccountExpandableFields[keyof typeof AccountExpandableFields];

export interface IExpandableOpts {
expand?: AccountExpandableField[];
}

export interface IConnectListOpts extends IResourceListOpts, IExpandableOpts {}

export const AccountProductsEligibleForAutomaticExecution = [
'account_attribute',
'balance',
'card_brand',
'update',
'payoff',
] as const;

export const AccountSubscriptionsEligibleForAutomaticExecution = [
'card_brand',
'update',
'update.snapshot',
'transaction',
] as const;
Comment on lines +5 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These already exist in the resources/Account/types.ts file. We should only maintain them in one location.


export type AccountProduct = typeof AccountProductsEligibleForAutomaticExecution[number];
export type AccountSubscription = typeof AccountSubscriptionsEligibleForAutomaticExecution[number];

export interface IConnectCreateOpts {
products?: AccountProduct[];
subscriptions?: AccountSubscription[];
}


export default class EntityConnect extends Resource {
constructor(config: Configuration) {
super(config.addPath('connect'));
Expand All @@ -14,8 +58,8 @@ export default class EntityConnect extends Resource {
* @returns Returns a Connect object.
*/

async retrieve(cxn_id: string) {
return super._getWithId<IResponse<IEntityConnect>>(cxn_id);
async retrieve(cxn_id: string, opts: IExpandableOpts = {}) {
return super._getWithSubPathAndParams<IResponse<IEntityConnect>>(cxn_id, opts);
}

/**
Expand All @@ -24,7 +68,7 @@ export default class EntityConnect extends Resource {
* @returns Returns a list of Connect objects.
*/

async list(opts?: IResourceListOpts) {
async list(opts?: IConnectListOpts) {
return super._list<IResponse<IEntityConnect>>(opts);
}

Expand All @@ -34,7 +78,7 @@ export default class EntityConnect extends Resource {
* @returns Returns a Connect object.
*/

async create() {
return super._create<IResponse<IEntityConnect>, {}>({});
async create(opts: IConnectCreateOpts = {}, params: IExpandableOpts = {}) {
return super._create<IResponse<IEntityConnect>, IConnectCreateOpts, IExpandableOpts>(opts, params);
}
};
61 changes: 41 additions & 20 deletions test/resources/Account.tests.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { should } from 'chai';
import { should, expect } from 'chai';
import { describe } from 'mocha';
import { client } from '../config';
import { awaitResults } from '../utils';
Expand Down Expand Up @@ -299,7 +299,7 @@ describe('Accounts - core methods tests', () => {
id: card_create_response.id,
account_id: test_credit_card_account.id,
network: 'visa',
status: 'completed',
status: 'in_progress',
issuer: card_create_response.issuer,
last4: '1580',
brands: card_create_response.brands,
Expand All @@ -311,6 +311,7 @@ describe('Accounts - core methods tests', () => {
};

card_create_response.should.be.eql(expect_results);
await new Promise(r => setTimeout(r, 2000))
});

it('should successfully retrieve a card for an account.', async () => {
Expand All @@ -319,22 +320,24 @@ describe('Accounts - core methods tests', () => {
.cardBrands
.retrieve(card_create_response.id);

const expect_results: IAccountCardBrand = {
id: card_create_response.id,
account_id: test_credit_card_account.id,
network: 'visa',
status: 'completed',
issuer: card_retrieve_response.issuer,
last4: '1580',
brands: card_create_response.brands,
shared: false,
source: card_retrieve_response.source,
error: null,
created_at: card_retrieve_response.created_at,
updated_at: card_retrieve_response.updated_at
};

card_retrieve_response.should.be.eql(expect_results);
expect(card_retrieve_response.id).to.equal(card_create_response.id);
expect(card_retrieve_response.account_id).to.equal(test_credit_card_account.id);
expect(card_retrieve_response.network).to.equal('visa');
expect(card_retrieve_response.status).to.equal('completed');
expect(card_retrieve_response.issuer).to.equal(card_create_response.issuer);
expect(card_retrieve_response.last4).to.equal('1580');
expect(card_retrieve_response.shared).to.equal(false);
expect(card_retrieve_response.source).to.equal('network');
expect(card_retrieve_response.error).to.be.null;
expect(card_retrieve_response.created_at).to.be.a('string');
expect(card_retrieve_response.updated_at).to.be.a('string');

const brand = card_retrieve_response.brands?.[0];
expect(brand).to.exist;
expect(brand.id).to.equal('brand_UBwVzXjpP4PJ6');
expect(brand.name).to.equal('Chase Sapphire Reserve');
expect(brand.url).to.equal('https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png');
expect(brand.art_id).to.be.a('string').and.match(/^art_/);
Comment on lines +323 to +340
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason you want to do it this way?

});

it('should successfully list card brands for an account.', async () => {
Expand All @@ -346,8 +349,26 @@ describe('Accounts - core methods tests', () => {
};

const card_brands = await awaitResults(listCardBrands);

card_brands[0].should.be.eql(card_create_response);
const result = card_brands[0];

expect(result.id).to.equal(card_create_response.id);
expect(result.account_id).to.equal(test_credit_card_account.id);
expect(result.network).to.equal('visa');
expect(result.status).to.equal('completed');
expect(result.issuer).to.equal(card_create_response.issuer);
expect(result.last4).to.equal('1580');
expect(result.shared).to.equal(false);
expect(result.source).to.equal('network');
expect(result.error).to.be.null;
expect(result.created_at).to.be.a('string');
expect(result.updated_at).to.be.a('string');

const brand = result.brands?.[0];
expect(brand).to.exist;
expect(brand.id).to.equal('brand_UBwVzXjpP4PJ6');
expect(brand.name).to.equal('Chase Sapphire Reserve');
expect(brand.url).to.equal('https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png');
expect(brand.art_id).to.be.a('string').and.match(/^art_/);
});
});

Expand Down
4 changes: 2 additions & 2 deletions test/resources/Report.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('Reports - core methods tests', () => {
type: 'payments.created.current',
url: `https://dev.methodfi.com/reports/${reports_create_response.id}/download`,
status: 'completed',
metadata: null,
metadata: reports_create_response.metadata,
created_at: reports_create_response.created_at,
updated_at: reports_create_response.updated_at,
};
Expand All @@ -41,7 +41,7 @@ describe('Reports - core methods tests', () => {
type: 'payments.created.current',
url: `https://dev.methodfi.com/reports/${reports_create_response.id}/download`,
status: 'completed',
metadata: null,
metadata: reports_create_response.metadata,
created_at: reports_retrieve_response.created_at,
updated_at: reports_retrieve_response.updated_at,
};
Expand Down