Skip to content

Commit f8efc41

Browse files
committed
challenge/30095006 - Multiple invitations by email
1 parent 5d31391 commit f8efc41

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

src/routes/projectMemberInvites/create.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const buildCreateInvitePromises = (req, invite, invites, data, failed) => {
8080
if (invite.emails) {
8181
// if for some emails there are already existent users, we will invite them by userId,
8282
// to avoid sending them registration email
83-
return util.lookupUserEmails(req, invite.emails)
83+
return util.lookupMultipleUserEmails(req, invite.emails, 5)
8484
.then((existentUsers) => {
8585
// existent user we will invite by userId and email
8686
const existentUsersWithNumberId = existentUsers.map((user) => {

src/routes/projectMemberInvites/create.spec.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ describe('Project Member Invite create', () => {
147147
server.services.pubsub.publish.restore();
148148
sinon.stub(server.services.pubsub, 'init', () => {});
149149
sinon.stub(server.services.pubsub, 'publish', () => {});
150-
// by default mock lookupUserEmails return nothing so all the cases are not broken
150+
// by default mock lookupMultipleUserEmails return nothing so all the cases are not broken
151151
sandbox.stub(util, 'getUserRoles', () => Promise.resolve([]));
152-
sandbox.stub(util, 'lookupUserEmails', () => Promise.resolve([]));
152+
sandbox.stub(util, 'lookupMultipleUserEmails', () => Promise.resolve([]));
153153
sandbox.stub(util, 'getMemberDetailsByUserIds', () => Promise.resolve([{
154154
userId: 40051333,
155155
firstName: 'Admin',
@@ -366,8 +366,8 @@ describe('Project Member Invite create', () => {
366366
}),
367367
});
368368
sandbox.stub(util, 'getHttpClient', () => mockHttpClient);
369-
util.lookupUserEmails.restore();
370-
sandbox.stub(util, 'lookupUserEmails', () => Promise.resolve([{
369+
util.lookupMultipleUserEmails.restore();
370+
sandbox.stub(util, 'lookupMultipleUserEmails', () => Promise.resolve([{
371371
id: '12345',
372372
email: 'hello@world.com',
373373
}]));

src/util.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,68 @@ _.assignIn(util, {
463463
});
464464
},
465465

466+
/**
467+
* Lookup user handles from multiple emails
468+
* @param {Object} req request
469+
* @param {Array} userEmails user emails
470+
* @param {Number} maximumRequests limit number of request on one batch
471+
* @param {Boolean} isPattern flag to indicate that pattern matching is required or not
472+
* @return {Promise} promise
473+
*/
474+
lookupMultipleUserEmails(req, userEmails, maximumRequests, isPattern = false) {
475+
req.log.debug(`identityServiceEndpoint: ${config.get('identityServiceEndpoint')}`);
476+
477+
const httpClient = util.getHttpClient({ id: req.id, log: req.log });
478+
// request generator function
479+
const generateRequest = ({ token, email }) => {
480+
let filter = `email=${email}`;
481+
if (isPattern) {
482+
filter += '&like=true';
483+
}
484+
return httpClient.get(`${config.get('identityServiceEndpoint')}users`, {
485+
headers: {
486+
Authorization: `Bearer ${token}`,
487+
Accept: 'application/json',
488+
'Content-Type': 'application/json',
489+
},
490+
params: {
491+
fields: 'handle,id,email',
492+
filter,
493+
},
494+
// set longer timeout as default 3000 could be not enough for identity service response
495+
timeout: 15000,
496+
});
497+
};
498+
// send batch of requests, one batch at one time
499+
const sendBatch = (options) => {
500+
const token = options.token;
501+
const emails = options.emails;
502+
const users = options.users || [];
503+
const batch = options.batch || 0;
504+
const start = batch * maximumRequests;
505+
const end = (batch + 1) * maximumRequests;
506+
const requests = emails.slice(start, end).map(userEmail =>
507+
generateRequest({ token, email: userEmail }));
508+
return Promise.all(requests)
509+
.then((responses) => {
510+
const data = responses.reduce((contents, response) => {
511+
const content = _.get(response, 'data.result.content', []);
512+
return _.concat(contents, content);
513+
}, users);
514+
req.log.debug(`UserHandle response batch-${batch}`, data);
515+
if (end < emails.length) {
516+
return sendBatch({ token, users: data, emails, batch: batch + 1 });
517+
}
518+
return data;
519+
});
520+
};
521+
return util.getM2MToken()
522+
.then((m2mToken) => {
523+
req.log.debug(`Bearer ${m2mToken}`);
524+
return sendBatch({ token: m2mToken, emails: userEmails });
525+
});
526+
},
527+
466528
/**
467529
* Filter only members of topcoder team
468530
* @param {Array} members project members

0 commit comments

Comments
 (0)