Skip to content

Commit

Permalink
feat(sc-57429): Support Opportunities API (#98)
Browse files Browse the repository at this point in the history
* feat(sc-57429): Support Opportunities API

* feat(sc-57429): Support Opportunities API : fix typo in tests

* feat(sc-57429): Support Opportunities API : fix tests data
  • Loading branch information
kamilpavlicko authored Mar 25, 2024
1 parent c248d74 commit 4c53578
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 0 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ ChartMogul.Customer.createContact(config, customerUuid, data)

ChartMogul.Customer.notes(config, customerUuid, { per_page: 10, cursor: 'cursor==' })
ChartMogul.Customer.createNote(config, customerUuid, data)

ChartMogul.Customer.opportunities(config, customerUuid, { per_page: 10, cursor: 'cursor==' })
ChartMogul.Customer.createOpportunity(config, customerUuid, data)
```

#### [Contacts](https://dev.chartmogul.com/docs/contacts)
Expand All @@ -151,6 +154,16 @@ ChartMogul.CustomerNote.all(config, { per_page: 10, cursor: 'cursor==', customer

```

#### [Opportunities](https://dev.chartmogul.com/docs/opportunities)

```js
ChartMogul.Opportunity.create(config, data)
ChartMogul.Opportunity.retrieve(config, opportunityUuid)
ChartMogul.Opportunity.patch(config, opportunityUuid, data)
ChartMogul.Opportunity.destroy(config, opportunityUuid)
ChartMogul.Opportunity.all(config, { per_page: 10, cursor: 'cursor==', customer_uuid: customerUuid})
```


#### [Plans](https://dev.chartmogul.com/docs/plans)

Expand Down
2 changes: 2 additions & 0 deletions lib/chartmogul.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const Customer = require('./chartmogul/customer');
const CustomerNote = require('./chartmogul/customer-note');
const Contact = require('./chartmogul/contact');
const DataSource = require('./chartmogul/data-source');
const Opportunity = require('./chartmogul/opportunity');
const Plan = require('./chartmogul/plan');
const PlanGroup = require('./chartmogul/plan-group');
const Ping = require('./chartmogul/ping');
Expand Down Expand Up @@ -38,6 +39,7 @@ const ChartMogul = {
Import,
Invoice,
Metrics,
Opportunity,
Ping,
Plan,
PlanGroup,
Expand Down
11 changes: 11 additions & 0 deletions lib/chartmogul/customer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const Resource = require('./resource');
const util = require('./util');
const CustomerNote = require('./customer-note');
const Opportunity = require('./opportunity');

class Customer extends Resource {
static get path () {
Expand Down Expand Up @@ -38,6 +39,16 @@ class Customer extends Resource {
const path = util.expandPath(CustomerNote.path, []);
return Resource.request(config, 'POST', path, { ...params, customer_uuid: customerId }, callback);
}

static opportunities (config, customerId, params, callback) {
const path = util.expandPath(Opportunity.path, []);
return Resource.request(config, 'GET', path, { ...params, customer_uuid: customerId }, callback);
}

static createOpportunity (config, customerId, params, callback) {
const path = util.expandPath(Opportunity.path, []);
return Resource.request(config, 'POST', path, { ...params, customer_uuid: customerId }, callback);
}
}

// @Override
Expand Down
11 changes: 11 additions & 0 deletions lib/chartmogul/opportunity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict';

const Resource = require('./resource');

class Opportunity extends Resource {
static get path () {
return '/v1/opportunities{/opportunityUuid}';
}
}

module.exports = Opportunity;
83 changes: 83 additions & 0 deletions test/chartmogul/customer.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,89 @@ describe('Customer', () => {
expect(res.has_more).to.eql(false);
});
});

it('creates a new opportunity from a customer', async () => {
const customerUuid = 'cus_00000000-0000-0000-0000-000000000000';
const postBody = {
customer_uuid: customerUuid,
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2023-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: [{ key: 'from_campaign', value: true }]
};

nock(config.API_BASE)
.post('/v1/opportunities', postBody)
.reply(200, {
uuid: '00000000-0000-0000-0000-000000000000',
customer_uuid: 'cus_00000000-0000-0000-0000-000000000000',
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2023-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: { from_campaign: true },
created_at: '2024-03-13T07:33:28.356Z',
updated_at: '2024-03-13T07:33:28.356Z'
});

const opportunity = await Customer.createOpportunity(config, customerUuid, postBody);
expect(opportunity.uuid).to.be.equal('00000000-0000-0000-0000-000000000000');
expect(opportunity.customer_uuid).to.be.equal(customerUuid);
expect(opportunity.owner).to.be.equal('[email protected]');
expect(opportunity.pipeline).to.be.equal('New business 1');
expect(opportunity.pipeline_stage).to.be.equal('Discovery');
expect(opportunity.estimated_close_date).to.be.equal('2023-12-22');
expect(opportunity.currency).to.be.equal('USD');
expect(opportunity.amount_in_cents).to.be.equal(100);
expect(opportunity.type).to.be.equal('recurring');
expect(opportunity.forecast_category).to.be.equal('pipeline');
expect(opportunity.win_likelihood).to.be.equal(3);
expect(opportunity.custom).to.deep.equal({ from_campaign: true });
});

it('gets all opportunities from a customer', async () => {
const customerUuid = 'cus_00000000-0000-0000-0000-000000000000';

nock(config.API_BASE)
.get(`/v1/opportunities?customer_uuid=${customerUuid}`)
.reply(200, {
entries: [{
uuid: '00000000-0000-0000-0000-000000000000',
customer_uuid: 'cus_00000000-0000-0000-0000-000000000000',
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2023-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: { from_campaign: true },
created_at: '2024-03-13T07:33:28.356Z',
updated_at: '2024-03-13T07:33:28.356Z'
}],
cursor: 'MjAyMy0wMy0xM1QxMjowMTozMi44MD==',
has_more: false
});

const opportunities = await Customer.opportunities(config, customerUuid);
expect(opportunities).to.have.property('entries');
expect(opportunities.entries).to.be.instanceof(Array);
expect(opportunities.cursor).to.eql('MjAyMy0wMy0xM1QxMjowMTozMi44MD==');
expect(opportunities.has_more).to.eql(false);
});
});

/** Suite that originally belonged in the Enrichment module.
Expand Down
178 changes: 178 additions & 0 deletions test/chartmogul/opportunity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
'use strict';

const ChartMogul = require('../../lib/chartmogul');
const config = new ChartMogul.Config('token');
const expect = require('chai').expect;
const nock = require('nock');
const Opportunity = ChartMogul.Opportunity;

describe('Opportunity', () => {
it('creates a opportunity for a customer', async () => {
const uuid = 'cus_00000000-0000-0000-0000-000000000000';
const postBody = {
customer_uuid: uuid,
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2023-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: [{ key: 'from_campaign', value: true }]
};

nock(config.API_BASE)
.post('/v1/opportunities', postBody)
.reply(200, {
uuid: '00000000-0000-0000-0000-000000000000',
customer_uuid: 'cus_00000000-0000-0000-0000-000000000000',
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2023-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: { from_campaign: true },
created_at: '2024-03-13T07:33:28.356Z',
updated_at: '2024-03-13T07:33:28.356Z'
});

const opportunity = await Opportunity.create(config, postBody);
expect(opportunity.customer_uuid).to.be.equal(uuid);
expect(opportunity.owner).to.be.equal('[email protected]');
expect(opportunity.pipeline).to.be.equal('New business 1');
expect(opportunity.pipeline_stage).to.be.equal('Discovery');
expect(opportunity.estimated_close_date).to.be.equal('2023-12-22');
expect(opportunity.currency).to.be.equal('USD');
expect(opportunity.amount_in_cents).to.be.equal(100);
expect(opportunity.type).to.be.equal('recurring');
expect(opportunity.forecast_category).to.be.equal('pipeline');
expect(opportunity.win_likelihood).to.be.equal(3);
expect(opportunity.custom).to.deep.equal({ from_campaign: true });
});

it('lists all opportunities from a customer', async () => {
const uuid = 'cus_00000000-0000-0000-0000-000000000000';

nock(config.API_BASE)
.get(`/v1/opportunities/${uuid}`)
.reply(200, {
entries: [
{
uuid: '00000000-0000-0000-0000-000000000000',
customer_uuid: 'cus_00000000-0000-0000-0000-000000000000',
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2023-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: { from_campaign: true },
created_at: '2024-03-13T07:33:28.356Z',
updated_at: '2024-03-13T07:33:28.356Z'
}
]
});

const opportunity = await Opportunity.all(config, uuid);
expect(opportunity.entries).to.have.length(1);
});

it('retrieves an opportunity', async () => {
const uuid = '00000000-0000-0000-0000-000000000000';

nock(config.API_BASE)
.get(`/v1/opportunities/${uuid}`)
.reply(200, {
uuid: '00000000-0000-0000-0000-000000000000',
customer_uuid: 'cus_00000000-0000-0000-0000-000000000000',
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2023-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: { from_campaign: true },
created_at: '2024-03-13T07:33:28.356Z',
updated_at: '2024-03-13T07:33:28.356Z'
});

const opportunity = await Opportunity.retrieve(config, uuid);
expect(opportunity.uuid).to.be.equal(uuid);
expect(opportunity.customer_uuid).to.be.equal(
'cus_00000000-0000-0000-0000-000000000000'
);
expect(opportunity.owner).to.be.equal('[email protected]');
expect(opportunity.pipeline).to.be.equal('New business 1');
expect(opportunity.pipeline_stage).to.be.equal('Discovery');
expect(opportunity.estimated_close_date).to.be.equal('2023-12-22');
expect(opportunity.currency).to.be.equal('USD');
expect(opportunity.amount_in_cents).to.be.equal(100);
expect(opportunity.type).to.be.equal('recurring');
expect(opportunity.forecast_category).to.be.equal('pipeline');
expect(opportunity.win_likelihood).to.be.equal(3);
expect(opportunity.custom).to.deep.equal({ from_campaign: true });
});

it('updates an opportunity', async () => {
const uuid = '00000000-0000-0000-0000-000000000000';
const postBody = {
estimated_close_date: '2024-12-22'
};

nock(config.API_BASE)
.patch(`/v1/opportunities/${uuid}`, postBody)
.reply(200, {
uuid: '00000000-0000-0000-0000-000000000000',
customer_uuid: 'cus_00000000-0000-0000-0000-000000000000',
owner: '[email protected]',
pipeline: 'New business 1',
pipeline_stage: 'Discovery',
estimated_close_date: '2024-12-22',
currency: 'USD',
amount_in_cents: 100,
type: 'recurring',
forecast_category: 'pipeline',
win_likelihood: 3,
custom: { from_campaign: true },
created_at: '2024-03-13T07:33:28.356Z',
updated_at: '2024-03-13T07:33:28.356Z'
});

const opportunity = await Opportunity.patch(config, uuid, postBody);
expect(opportunity.uuid).to.be.equal(uuid);
expect(opportunity.customer_uuid).to.be.equal(
'cus_00000000-0000-0000-0000-000000000000'
);
expect(opportunity.owner).to.be.equal('[email protected]');
expect(opportunity.pipeline).to.be.equal('New business 1');
expect(opportunity.pipeline_stage).to.be.equal('Discovery');
expect(opportunity.estimated_close_date).to.be.equal('2024-12-22');
expect(opportunity.currency).to.be.equal('USD');
expect(opportunity.amount_in_cents).to.be.equal(100);
expect(opportunity.type).to.be.equal('recurring');
expect(opportunity.forecast_category).to.be.equal('pipeline');
expect(opportunity.win_likelihood).to.be.equal(3);
expect(opportunity.custom).to.deep.equal({ from_campaign: true });
});

it('deletes an opportunity', async () => {
const uuid = '00000000-0000-0000-0000-000000000000';

nock(config.API_BASE).delete(`/v1/opportunities/${uuid}`).reply(204);

const result = await Opportunity.destroy(config, uuid);
expect(result).to.deep.equal({});
});
});

0 comments on commit 4c53578

Please sign in to comment.