From b88f083af54223c3fd1ad1296f5cbceb02c47290 Mon Sep 17 00:00:00 2001 From: gets0ul Date: Wed, 22 Jan 2020 16:35:46 +0700 Subject: [PATCH 1/4] Enable admin user to join project as manager. --- src/routes/projectMembers/create.js | 6 +- src/routes/projectMembers/create.spec.js | 84 +++++++++++++++++++++++- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/routes/projectMembers/create.js b/src/routes/projectMembers/create.js index cb72ebc7..6b69fe4f 100644 --- a/src/routes/projectMembers/create.js +++ b/src/routes/projectMembers/create.js @@ -38,8 +38,8 @@ module.exports = [ targetRole = _.get(req, 'body.role'); if (PROJECT_MEMBER_ROLE.MANAGER === targetRole && - !util.hasRoles(req, [USER_ROLE.MANAGER])) { - const err = new Error(`Only manager is able to join as ${targetRole}`); + !util.hasRoles(req, [USER_ROLE.TOPCODER_ADMIN, USER_ROLE.CONNECT_ADMIN, USER_ROLE.MANAGER])) { + const err = new Error(`Only admin or manager is able to join as ${targetRole}`); err.status = 401; return next(err); } @@ -96,7 +96,7 @@ module.exports = [ err.status = 401; return next(err); } - } else if (util.hasRoles(req, [USER_ROLE.MANAGER, USER_ROLE.CONNECT_ADMIN])) { + } else if (util.hasRoles(req, [USER_ROLE.MANAGER, USER_ROLE.CONNECT_ADMIN, USER_ROLE.TOPCODER_ADMIN])) { targetRole = PROJECT_MEMBER_ROLE.MANAGER; } else if (util.hasRoles(req, [ USER_ROLE.TOPCODER_ACCOUNT_MANAGER, diff --git a/src/routes/projectMembers/create.spec.js b/src/routes/projectMembers/create.spec.js index 7e193990..7830096d 100644 --- a/src/routes/projectMembers/create.spec.js +++ b/src/routes/projectMembers/create.spec.js @@ -9,7 +9,14 @@ import util from '../../util'; import server from '../../app'; import testUtil from '../../tests/util'; import busApi from '../../services/busApi'; -import { USER_ROLE, BUS_API_EVENT, RESOURCES, CONNECT_NOTIFICATION_EVENT, INVITE_STATUS } from '../../constants'; +import { + USER_ROLE, + BUS_API_EVENT, + RESOURCES, + CONNECT_NOTIFICATION_EVENT, + INVITE_STATUS, + PROJECT_MEMBER_ROLE, +} from '../../constants'; const should = chai.should(); @@ -201,6 +208,81 @@ describe('Project Members create', () => { }); }); + it('should return 201 and register admin as manager', (done) => { + const mockHttpClient = _.merge(testUtil.mockHttpClient, { + get: () => Promise.resolve({ + status: 200, + data: { + id: 'requesterId', + version: 'v3', + result: { + success: true, + status: 200, + content: [{ + roleName: USER_ROLE.MANAGER, + }], + }, + }, + }), + post: () => Promise.resolve({ + status: 200, + data: { + id: 'requesterId', + version: 'v3', + result: { + success: true, + status: 200, + content: {}, + }, + }, + }), + }); + sandbox.stub(util, 'getHttpClient', () => mockHttpClient); + request(server) + .post(`/v5/projects/${project1.id}/members/`) + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .expect('Content-Type', /json/) + .expect(201) + .end((err, res) => { + if (err) { + done(err); + } else { + const resJson = res.body; + should.exist(resJson); + resJson.role.should.equal('manager'); + resJson.isPrimary.should.be.truthy; + resJson.projectId.should.equal(project1.id); + resJson.userId.should.equal(40051333); + server.services.pubsub.publish.calledWith('project.member.added').should.be.true; + done(); + } + }); + }); + + it('should return 401 if register admin as role other than manager (copilot) ', (done) => { + request(server) + .post(`/v5/projects/${project1.id}/members/`) + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .send({ role: PROJECT_MEMBER_ROLE.COPILOT }) + .expect('Content-Type', /json/) + .expect(401, done); + }); + + it('should return 401 if register admin as role other than manager (project manager) ', (done) => { + request(server) + .post(`/v5/projects/${project1.id}/members/`) + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .send({ role: PROJECT_MEMBER_ROLE.PROJECT_MANAGER }) + .expect('Content-Type', /json/) + .expect(401, done); + }); + describe('Bus api', () => { let createEventSpy; From d53de730ced183daed98c4b266e5f62e0e187360 Mon Sep 17 00:00:00 2001 From: gets0ul Date: Thu, 23 Jan 2020 03:27:00 +0700 Subject: [PATCH 2/4] Adding support to search project via customer/manager handles --- src/routes/projects/list.js | 4 +-- src/routes/projects/list.spec.js | 46 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/routes/projects/list.js b/src/routes/projects/list.js index c8ac798b..0c37cb5a 100755 --- a/src/routes/projects/list.js +++ b/src/routes/projects/list.js @@ -333,13 +333,13 @@ const parseElasticSearchCriteria = (criteria, fields, order) => { if (_.has(criteria, 'filters.customer')) { mustQuery = _.concat(mustQuery, setFilter('customer', criteria.filters.customer, - ['members.firstName', 'members.lastName'])); + ['members.firstName', 'members.lastName', 'members.handle'])); } if (_.has(criteria, 'filters.manager')) { mustQuery = _.concat(mustQuery, setFilter('manager', criteria.filters.manager, - ['members.firstName', 'members.lastName'])); + ['members.firstName', 'members.lastName', 'members.handle'])); } if (_.has(criteria, 'filters.userId') || _.has(criteria, 'filters.email')) { diff --git a/src/routes/projects/list.spec.js b/src/routes/projects/list.spec.js index 5d649677..0dbe713e 100644 --- a/src/routes/projects/list.spec.js +++ b/src/routes/projects/list.spec.js @@ -683,6 +683,52 @@ describe('LIST Project', () => { }); }); + it('should return all projects that match when filtering by customer handle', (done) => { + request(server) + .get('/v5/projects/?customer=*tourist*') + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .expect('Content-Type', /json/) + .expect(200) + .end((err, res) => { + if (err) { + done(err); + } else { + const resJson = res.body; + should.exist(resJson); + resJson.should.have.lengthOf(1); + resJson[0].name.should.equal('test1'); + resJson[0].members.should.have.deep.property('[0].role', 'customer'); + resJson[0].members[0].userId.should.equal(40051331); + done(); + } + }); + }); + + it('should return all projects that match when filtering by manager handle', (done) => { + request(server) + .get('/v5/projects/?manager=*_handle') + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .expect('Content-Type', /json/) + .expect(200) + .end((err, res) => { + if (err) { + done(err); + } else { + const resJson = res.body; + should.exist(resJson); + resJson.should.have.lengthOf(1); + resJson[0].name.should.equal('test3'); + resJson[0].members.should.have.deep.property('[0].role', 'manager'); + resJson[0].members[0].userId.should.equal(40051334); + done(); + } + }); + }); + it('should return list of projects ordered ascending by lastActivityAt when sort column is "lastActivityAt"', (done) => { request(server) .get('/v5/projects/?sort=lastActivityAt') From f1247054362223491a6fa780f094f915d1b21b48 Mon Sep 17 00:00:00 2001 From: yoution Date: Thu, 23 Jan 2020 13:53:09 +0800 Subject: [PATCH 3/4] #429 Update Postman file --- docs/Project API.postman_collection.json | 248 ++++++++++++++++++++++- 1 file changed, 247 insertions(+), 1 deletion(-) diff --git a/docs/Project API.postman_collection.json b/docs/Project API.postman_collection.json index cda37b99..930185eb 100644 --- a/docs/Project API.postman_collection.json +++ b/docs/Project API.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "2e0a1b99-3cb9-4c77-a562-7e6fe4956358", + "_postman_id": "49981b6e-f611-4016-999e-737ef4103435", "name": "Project API", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, @@ -5837,6 +5837,252 @@ ], "protocolProfileBehavior": {} }, + { + "name": "Org Config", + "item": [ + { + "name": "Create org config", + "event": [ + { + "listen": "test", + "script": { + "id": "fbc45946-a3f2-433a-8ec5-0af82b69d2bd", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + " console.log(pm.response.json())", + " pm.environment.set(\"orgStrId\", pm.response.json().orgId);", + " pm.environment.set(\"orgConfigName\", pm.response.json().configName);", + " pm.environment.set(\"orgId\", pm.response.json().id);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Authorization", + "value": "Bearer {{jwt-token}}" + } + ], + "body": { + "mode": "raw", + "raw": "{ \n\t\"orgId\": \"testStr Id\",\n \"configName\": \"project_catefory_url\",\n \"configValue\": \"http://localhost/url\"\n}" + }, + "url": { + "raw": "{{api-url}}/projects/metadata/orgConfig", + "host": [ + "{{api-url}}" + ], + "path": [ + "projects", + "metadata", + "orgConfig" + ] + } + }, + "response": [] + }, + { + "name": "List org configs without orgId", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Authorization", + "value": "Bearer {{jwt-token}}" + } + ], + "url": { + "raw": "{{api-url}}/projects/metadata/orgConfig", + "host": [ + "{{api-url}}" + ], + "path": [ + "projects", + "metadata", + "orgConfig" + ] + } + }, + "response": [] + }, + { + "name": "List org configs with only orgId", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Authorization", + "value": "Bearer {{jwt-token}}" + } + ], + "url": { + "raw": "{{api-url}}/projects/metadata/orgConfig?orgId={{orgStrId}}", + "host": [ + "{{api-url}}" + ], + "path": [ + "projects", + "metadata", + "orgConfig" + ], + "query": [ + { + "key": "orgId", + "value": "{{orgStrId}}", + "description": "orgId can be array with ',', 'id1,id2'" + } + ] + } + }, + "response": [] + }, + { + "name": "List org configs with orgId and configName", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Authorization", + "value": "Bearer {{jwt-token}}" + } + ], + "url": { + "raw": "{{api-url}}/projects/metadata/orgConfig?orgId={{orgStrId}}&configName={{orgConfigName}}", + "host": [ + "{{api-url}}" + ], + "path": [ + "projects", + "metadata", + "orgConfig" + ], + "query": [ + { + "key": "orgId", + "value": "{{orgStrId}}", + "description": "orgId can be array with ',', 'id1,id2'" + }, + { + "key": "configName", + "value": "{{orgConfigName}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete org config", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Authorization", + "value": "Bearer {{jwt-token}}" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{api-url}}/projects/metadata/orgConfig/{{orgId}}", + "host": [ + "{{api-url}}" + ], + "path": [ + "projects", + "metadata", + "orgConfig", + "{{orgId}}" + ] + } + }, + "response": [] + }, + { + "name": "Update org config", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Authorization", + "value": "Bearer {{jwt-token}}" + } + ], + "body": { + "mode": "raw", + "raw": "{ \n\t\"orgId\": \"another orgId\",\n \"configName\": \"project_catefory_url\",\n \"configValue\": \"http://localhost/url\"\n}" + }, + "url": { + "raw": "{{api-url}}/projects/metadata/orgConfig/{{orgId}}", + "host": [ + "{{api-url}}" + ], + "path": [ + "projects", + "metadata", + "orgConfig", + "{{orgId}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "2e274cc9-22e6-4dd2-9eee-c4f1fd98253d", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "9d171dbf-2a50-4483-b172-ce240ac09413", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + }, { "name": "Product Category", "item": [ From 618fdb818e50a9a1da99999068ba8663687e7142 Mon Sep 17 00:00:00 2001 From: gets0ul Date: Thu, 23 Jan 2020 15:23:51 +0700 Subject: [PATCH 4/4] Fix test. --- src/routes/projectMembers/create.spec.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/routes/projectMembers/create.spec.js b/src/routes/projectMembers/create.spec.js index 7830096d..75a0c234 100644 --- a/src/routes/projectMembers/create.spec.js +++ b/src/routes/projectMembers/create.spec.js @@ -219,23 +219,11 @@ describe('Project Members create', () => { success: true, status: 200, content: [{ - roleName: USER_ROLE.MANAGER, + roleName: USER_ROLE.TOPCODER_ADMIN, }], }, }, }), - post: () => Promise.resolve({ - status: 200, - data: { - id: 'requesterId', - version: 'v3', - result: { - success: true, - status: 200, - content: {}, - }, - }, - }), }); sandbox.stub(util, 'getHttpClient', () => mockHttpClient); request(server)