Skip to content

Commit f986af1

Browse files
committed
fix: sfdc billing accounts
- fixed permissions - renamed variables to keep them clear - fixed and implemented unit tests - fixed code for the Salesforce Service
1 parent 76d88f9 commit f986af1

File tree

5 files changed

+74
-22
lines changed

5 files changed

+74
-22
lines changed

src/constants.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ export const M2M_SCOPES = {
274274
ALL: 'all:projects',
275275
READ: 'read:projects',
276276
WRITE: 'write:projects',
277-
READ_BILLING_ACCOUNTS: 'read:user-billing-accounts',
278-
WRITE_BILLING_ACCOUNTS: 'write:projects-billing-accounts',
277+
READ_USER_BILLING_ACCOUNTS: 'read:user-billing-accounts',
278+
WRITE_PROJECTS_BILLING_ACCOUNTS: 'write:projects-billing-accounts',
279279
},
280280
PROJECT_MEMBERS: {
281281
ALL: 'all:project-members',

src/permissions/constants.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,15 @@ const SCOPES_PROJECTS_WRITE = [
9696
*/
9797
const SCOPES_PROJECTS_READ_AVL_BILLING_ACCOUNTS = [
9898
M2M_SCOPES.CONNECT_PROJECT_ADMIN,
99-
M2M_SCOPES.READ_BILLING_ACCOUNTS,
100-
M2M_SCOPES.PROJECTS.ALL,
99+
M2M_SCOPES.READ_USER_BILLING_ACCOUNTS,
101100
];
102101

103102
/**
104103
* M2M scopes to "write" billingAccountId property
105104
*/
106-
const SCOPES_PROJECTS_WRITE_BILLING_ACCOUNTS = [
105+
const SCOPES_PROJECTS_WRITE_PROJECTS_BILLING_ACCOUNTS = [
107106
M2M_SCOPES.CONNECT_PROJECT_ADMIN,
108-
M2M_SCOPES.PROJECTS.WRITE_BILLING_ACCOUNTS,
107+
M2M_SCOPES.PROJECTS.WRITE_PROJECTS_BILLING_ACCOUNTS,
109108
];
110109

111110
/**
@@ -240,7 +239,7 @@ export const PERMISSION = { // eslint-disable-line import/prefer-default-export
240239
USER_ROLE.MANAGER,
241240
USER_ROLE.TOPCODER_ADMIN,
242241
],
243-
scopes: SCOPES_PROJECTS_WRITE_BILLING_ACCOUNTS,
242+
scopes: SCOPES_PROJECTS_WRITE_PROJECTS_BILLING_ACCOUNTS,
244243
},
245244

246245
DELETE_PROJECT: {
@@ -270,7 +269,11 @@ export const PERMISSION = { // eslint-disable-line import/prefer-default-export
270269
group: 'Project Billing Accounts',
271270
description: 'Who can view the Billing Accounts available for the project',
272271
},
273-
topcoderRoles: ALL,
272+
projectRoles: [
273+
...PROJECT_ROLES_MANAGEMENT,
274+
PROJECT_MEMBER_ROLE.COPILOT,
275+
],
276+
topcoderRoles: TOPCODER_ROLES_ADMINS,
274277
scopes: SCOPES_PROJECTS_READ_AVL_BILLING_ACCOUNTS,
275278
},
276279

src/routes/billingAccounts/list.spec.js

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable no-unused-expressions */
2-
// import chai from 'chai';
2+
import chai from 'chai';
33
import request from 'supertest';
44
import sinon from 'sinon';
55

@@ -8,7 +8,24 @@ import server from '../../app';
88
import testUtil from '../../tests/util';
99
import SalesforceService from '../../services/salesforceService';
1010

11-
// const should = chai.should();
11+
chai.should();
12+
13+
// demo data which might be returned by the `SalesforceService.query`
14+
const billingAccountsData = [
15+
{
16+
sfBillingAccountId: 123,
17+
tcBillingAccountId: 123123,
18+
name: 'Billing Account 1',
19+
startDate: '2021-02-10T18:51:27Z',
20+
endDate: '2021-03-10T18:51:27Z',
21+
}, {
22+
sfBillingAccountId: 456,
23+
tcBillingAccountId: 456456,
24+
name: 'Billing Account 2',
25+
startDate: '2011-02-10T18:51:27Z',
26+
endDate: '2011-03-10T18:51:27Z',
27+
},
28+
];
1229

1330
describe('Project Billing Accounts list', () => {
1431
let project1;
@@ -54,10 +71,7 @@ describe('Project Billing Accounts list', () => {
5471
accessToken: 'mock',
5572
instanceUrl: 'mock_url',
5673
}));
57-
salesforceQuery = sinon.stub(SalesforceService, 'query', () => Promise.resolve([{
58-
accessToken: 'mock',
59-
instanceUrl: 'mock_url',
60-
}]));
74+
salesforceQuery = sinon.stub(SalesforceService, 'query', () => Promise.resolve(billingAccountsData));
6175
done();
6276
});
6377
});
@@ -80,17 +94,48 @@ describe('Project Billing Accounts list', () => {
8094
.expect(403, done);
8195
});
8296

83-
it('should return 403 for a regular user who is not a member of the project', (done) => {
97+
it('should return 403 for a customer user who is a member of the project', (done) => {
8498
request(server)
8599
.get(`/v5/projects/${project1.id}/billingAccounts`)
86100
.set({
87-
Authorization: `Bearer ${testUtil.jwts.member2}`,
101+
Authorization: `Bearer ${testUtil.jwts.member}`,
88102
})
89103
.send()
90104
.expect(403, done);
91105
});
92106

93-
it('should return all attachments to admin', (done) => {
107+
it('should return 403 for a topcoder user who is not a member of the project', (done) => {
108+
request(server)
109+
.get(`/v5/projects/${project1.id}/billingAccounts`)
110+
.set({
111+
Authorization: `Bearer ${testUtil.jwts.copilotManager}`,
112+
})
113+
.send()
114+
.expect(403, done);
115+
});
116+
117+
it('should return all billing accounts for a topcoder user who is a member of the project', (done) => {
118+
request(server)
119+
.get(`/v5/projects/${project1.id}/billingAccounts`)
120+
.set({
121+
Authorization: `Bearer ${testUtil.jwts.copilot}`,
122+
})
123+
.send()
124+
.expect(200)
125+
.end((err, res) => {
126+
if (err) {
127+
done(err);
128+
} else {
129+
const resJson = res.body;
130+
resJson.should.have.length(2);
131+
resJson.should.include(billingAccountsData[0]);
132+
resJson.should.include(billingAccountsData[1]);
133+
done();
134+
}
135+
});
136+
});
137+
138+
it('should return all billing accounts to admin', (done) => {
94139
request(server)
95140
.get(`/v5/projects/${project1.id}/billingAccounts`)
96141
.set({
@@ -104,13 +149,15 @@ describe('Project Billing Accounts list', () => {
104149
} else {
105150
const resJson = res.body;
106151
resJson.should.have.length(2);
107-
// TODO verify BA fields
152+
resJson.should.have.length(2);
153+
resJson.should.include(billingAccountsData[0]);
154+
resJson.should.include(billingAccountsData[1]);
108155
done();
109156
}
110157
});
111158
});
112159

113-
xit('should return all attachments using M2M token with "read:user-billing-accounts" scope', (done) => {
160+
it('should return all billing accounts using M2M token with "read:user-billing-accounts" scope', (done) => {
114161
request(server)
115162
.get(`/v5/projects/${project1.id}/billingAccounts`)
116163
.set({
@@ -124,7 +171,9 @@ describe('Project Billing Accounts list', () => {
124171
} else {
125172
const resJson = res.body;
126173
resJson.should.have.length(2);
127-
// TODO verify BA fields
174+
resJson.should.have.length(2);
175+
resJson.should.include(billingAccountsData[0]);
176+
resJson.should.include(billingAccountsData[1]);
128177
done();
129178
}
130179
});

src/services/salesforceService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,4 @@ class SalesforceService {
7474
}
7575
}
7676

77-
export default new SalesforceService();
77+
export default SalesforceService;

src/tests/util.js

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

0 commit comments

Comments
 (0)