Skip to content

Commit 244f0d6

Browse files
authored
Merge pull request #638 from imcaizheng/get-project-billing-account-add-unit-test
Fix/add unit tests for `GET /v5/projects/:projectId/billingAccount`
2 parents d7a7e92 + f13bdcc commit 244f0d6

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

src/routes/billingAccounts/get.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ module.exports = [
2929
attributes: ['id', 'billingAccountId'],
3030
raw: true,
3131
});
32+
if (!project) {
33+
const err = new Error(`Project with id "${projectId}" not found`);
34+
err.status = 404;
35+
throw err;
36+
}
3237
const billingAccountId = project.billingAccountId;
3338
if (!billingAccountId) {
3439
const err = new Error('Billing Account not found');
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/* eslint-disable no-unused-expressions */
2+
import chai from 'chai';
3+
import request from 'supertest';
4+
import sinon from 'sinon';
5+
6+
import models from '../../models';
7+
import server from '../../app';
8+
import testUtil from '../../tests/util';
9+
import SalesforceService from '../../services/salesforceService';
10+
11+
chai.should();
12+
13+
// demo data which might be returned by the `SalesforceService.query`
14+
const billingAccountData = {
15+
sfBillingAccountId: '123',
16+
tcBillingAccountId: 123123,
17+
name: 'Billing Account 1',
18+
startDate: '2021-02-10T18:51:27Z',
19+
endDate: '2021-03-10T18:51:27Z',
20+
};
21+
22+
describe('Project Billing Accounts list', () => {
23+
let project1;
24+
let project2;
25+
let salesforceAuthenticate;
26+
let salesforceQuery;
27+
28+
beforeEach((done) => {
29+
testUtil.clearDb()
30+
.then(() => testUtil.clearES())
31+
.then(() => models.Project.create({
32+
type: 'generic',
33+
directProjectId: 1,
34+
billingAccountId: 1,
35+
name: 'test1',
36+
description: 'test project1',
37+
status: 'draft',
38+
details: {},
39+
createdBy: 1,
40+
updatedBy: 1,
41+
lastActivityAt: 1,
42+
lastActivityUserId: '1',
43+
}).then((p) => {
44+
project1 = p;
45+
// create members
46+
return models.ProjectMember.create({
47+
userId: testUtil.userIds.copilot,
48+
projectId: project1.id,
49+
role: 'copilot',
50+
isPrimary: true,
51+
createdBy: 1,
52+
updatedBy: 1,
53+
}).then(() => models.ProjectMember.create({
54+
userId: testUtil.userIds.member,
55+
projectId: project1.id,
56+
role: 'customer',
57+
isPrimary: false,
58+
createdBy: 1,
59+
updatedBy: 1,
60+
}));
61+
})).then(() => models.Project.create({
62+
type: 'generic',
63+
directProjectId: 1,
64+
billingAccountId: null, // do not define billingAccountId
65+
name: 'test1',
66+
description: 'test project1',
67+
status: 'draft',
68+
details: {},
69+
createdBy: 1,
70+
updatedBy: 1,
71+
lastActivityAt: 1,
72+
lastActivityUserId: '1',
73+
}).then((p) => {
74+
project2 = p;
75+
// create members
76+
return models.ProjectMember.create({
77+
userId: testUtil.userIds.copilot,
78+
projectId: project2.id,
79+
role: 'copilot',
80+
isPrimary: true,
81+
createdBy: 1,
82+
updatedBy: 1,
83+
}).then(() => models.ProjectMember.create({
84+
userId: testUtil.userIds.member,
85+
projectId: project2.id,
86+
role: 'customer',
87+
isPrimary: false,
88+
createdBy: 1,
89+
updatedBy: 1,
90+
}));
91+
}))
92+
.then(() => {
93+
salesforceAuthenticate = sinon.stub(SalesforceService, 'authenticate', () => Promise.resolve({
94+
accessToken: 'mock',
95+
instanceUrl: 'mock_url',
96+
}));
97+
// eslint-disable-next-line
98+
salesforceQuery = sinon.stub(SalesforceService, 'queryBillingAccount', () => Promise.resolve(billingAccountData));
99+
done();
100+
});
101+
});
102+
103+
afterEach((done) => {
104+
salesforceAuthenticate.restore();
105+
salesforceQuery.restore();
106+
done();
107+
});
108+
109+
after((done) => {
110+
testUtil.clearDb(done);
111+
});
112+
113+
describe('Get /projects/{id}/billingAccounts', () => {
114+
it('should return 403 for anonymous user', (done) => {
115+
request(server)
116+
.get(`/v5/projects/${project1.id}/billingAccount`)
117+
.expect(403, done);
118+
});
119+
120+
it('should return 403 for admin', (done) => {
121+
request(server)
122+
.get(`/v5/projects/${project1.id}/billingAccount`)
123+
.set({
124+
Authorization: `Bearer ${testUtil.jwts.admin}`,
125+
})
126+
.send()
127+
.expect(403, done);
128+
});
129+
130+
it('should return 404 if the project is not found', (done) => {
131+
request(server)
132+
.get('/v5/projects/11223344/billingAccount')
133+
.set({
134+
Authorization: `Bearer ${testUtil.m2m['read:project-billing-account-details']}`,
135+
})
136+
.send()
137+
.expect(404, done);
138+
});
139+
140+
it('should return 404 if billing account is not defined in the project', (done) => {
141+
request(server)
142+
.get(`/v5/projects/${project2.id}/billingAccount`)
143+
.set({
144+
Authorization: `Bearer ${testUtil.m2m['read:project-billing-account-details']}`,
145+
})
146+
.send()
147+
.expect(404, done);
148+
});
149+
150+
it('should return billing account details using M2M token with "read:project-billing-account-details" scope',
151+
(done) => {
152+
request(server)
153+
.get(`/v5/projects/${project1.id}/billingAccount`)
154+
.set({
155+
Authorization: `Bearer ${testUtil.m2m['read:project-billing-account-details']}`,
156+
})
157+
.send()
158+
.expect(200)
159+
.end((err, res) => {
160+
if (err) {
161+
done(err);
162+
} else {
163+
const resJson = res.body;
164+
resJson.should.deep.equal(billingAccountData);
165+
done();
166+
}
167+
});
168+
});
169+
});
170+
});

src/tests/util.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)