Skip to content

Issue-4562 : Updated terms to use V5 API #203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions src/actions/terms.js
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ function getTermsInit(arg) {
* @return {Action}
*/
function getTermsDone(entity, tokens, mockAgreed) {
const service = getService(tokens.tokenV2);
const service = getService(tokens.tokenV3);
let termsPromise;

// if mockAgreed=true passed, then we create an array of 10 true which we pass to the
@@ -44,7 +44,7 @@ function getTermsDone(entity, tokens, mockAgreed) {

switch (entity.type) {
case 'challenge': {
termsPromise = service.getChallengeTerms(entity.id, mockAgreedArray);
termsPromise = service.getChallengeTerms(entity.terms, mockAgreedArray);
break;
}
case 'community': {
@@ -59,7 +59,7 @@ function getTermsDone(entity, tokens, mockAgreed) {
throw new Error(`Entity type '${entity.type}' is not supported by getTermsDone.`);
}

return termsPromise.then(res => ({ entity, terms: res.terms }));
return termsPromise.then(res => ({ entity, terms: res }));
}

/**
@@ -123,14 +123,14 @@ function checkStatusDone(entity, tokens) {
* @return {Promise} resolves to the list of term objects
*/
const checkStatus = maxAttempts => getTermsDone(entity, tokens, mockAgreed).then((res) => {
const allAgreed = _.every(res.terms, 'agreed');
const allAgreed = _.every(res, 'agreed');

// if not all terms are agreed and we still have some attempts to try
if (!allAgreed && maxAttempts > 1) {
return delay(TIME_OUT).then(() => checkStatus(maxAttempts - 1));
}

return res.terms;
return res;
});

return checkStatus(MAX_ATTEMPTS);
@@ -152,11 +152,11 @@ function getTermDetailsInit(termId) {
* @static
* @desc Creates an action that fetches details of the specified term.
* @param {Number|String} termId
* @param {String} tokenV2
* @param {String} tokenV3
* @return {Action}
*/
function getTermDetailsDone(termId, tokenV2) {
const service = getService(tokenV2);
function getTermDetailsDone(termId, tokenV3) {
const service = getService(tokenV3);
return service.getTermDetails(termId).then(details => ({ termId, details }));
}

@@ -175,11 +175,11 @@ function getDocuSignUrlInit(templateId) {
* @desc Creates an action that generates the url of DoduSign term
* @param {Number|String} templateId id of document template to sign
* @param {String} returnUrl callback url after finishing singing
* @param {String} tokenV2 auth token
* @param {String} tokenV3 auth token
* @return {Action}
*/
function getDocuSignUrlDone(templateId, returnUrl, tokenV2) {
const service = getService(tokenV2);
function getDocuSignUrlDone(templateId, returnUrl, tokenV3) {
const service = getService(tokenV3);
return service.getDocuSignUrl(templateId, returnUrl)
.then(resp => ({ templateId, docuSignUrl: resp.recipientViewUrl }));
}
@@ -198,11 +198,11 @@ function agreeTermInit(termId) {
* @static
* @desc Creates an action that agrees to a term.
* @param {Number|String} termId id of term
* @param {String} tokenV2 auth token
* @param {String} tokenV3 auth token
* @return {Action}
*/
function agreeTermDone(termId, tokenV2) {
const service = getService(tokenV2);
function agreeTermDone(termId, tokenV3) {
const service = getService(tokenV3);
return service.agreeTerm(termId).then(resp => ({ termId, success: resp.success }));
}

4 changes: 2 additions & 2 deletions src/reducers/reviewOpportunity.js
Original file line number Diff line number Diff line change
@@ -23,8 +23,8 @@ function buildRequiredTermsList(details) {
// Sometimes roles such as Primary Reviewer have no directly equal
// terms entry. Include the plain Reviewer terms when present as a back-up.
.filter(term => term.role === 'Reviewer' || _.includes(roles, term.role))
.map(term => _.pick(term, ['termsOfUseId', 'agreed', 'title'])),
term => term.termsOfUseId,
.map(term => _.pick(term, ['id', 'agreed', 'title'])),
term => term.id,
);

return requiredTerms || [];
2 changes: 1 addition & 1 deletion src/reducers/terms.js
Original file line number Diff line number Diff line change
@@ -181,7 +181,7 @@ function onAgreeTermDone(state, action) {
}
if (action.payload.success) {
const terms = _.cloneDeep(state.terms);
const term = _.find(terms, ['termsOfUseId', action.payload.termId]);
const term = _.find(terms, ['id', action.payload.termId]);
term.agreed = true;
const selectedTerm = _.find(terms, t => !t.agreed);
return {
77 changes: 30 additions & 47 deletions src/services/terms.js
Original file line number Diff line number Diff line change
@@ -8,61 +8,41 @@ import _ from 'lodash';
import { config } from 'topcoder-react-utils';

import { getService as getCommunityService } from './communities';
import { getService as getChallengeService } from './challenges';
import { getApi } from './api';

/**
* Service class.
*/
class TermsService {
/**
* @param {String} tokenV2 Optional. Auth token for Topcoder API v2.
* @param {String} tokenV3 Optional. Auth token for Topcoder API v3.
*/
constructor(tokenV2) {
constructor(tokenV3) {
this.private = {
api: getApi('V2', tokenV2),
tokenV2,
api: getApi('V5', tokenV3),
tokenV3,
};
}

/**
* get all terms of specified challenge
* @param {Number|String} challengeId id of the challenge
* @param {Array<String>} terms terms of the challenge
* @return {Promise} promise of the request result
*/
getChallengeTerms(challengeId) {
if (this.private.tokenV2) {
let registered = false;
return this.private.api.get(`/terms/${challengeId}?role=Submitter`)
.then(res => res.json())
.then((res) => {
if (res.error) {
if (res.error.details === 'You are already registered for this challenge.') {
registered = true;
}
return this.private.api.get(`/terms/${challengeId}?role=Submitter&noauth=true`)
.then((resp) => {
if (resp.ok) {
return resp.json().then((result) => {
if (registered) {
// eslint-disable-next-line no-param-reassign
_.forEach(result.terms, (t) => { t.agreed = true; });
}
return result;
});
}
return new Error(resp.statusText);
});
}
return res;
});
async getChallengeTerms(terms) {
if (this.private.tokenV3) {
const challengeService = getChallengeService(this.private.tokenV3);
const roleId = await challengeService.getRoleId('Submitter');
const registerTerms = _.filter(terms, t => t.roleId === roleId);

return Promise.all(_.map(registerTerms, term => this.getTermDetails(term.id)))
.then(challengeTerms => (
_.map(challengeTerms, term => _.pick(term, 'id', 'title', 'agreed'))
));
}
return this.private.api.get(`/terms/${challengeId}?role=Submitter&noauth=true`)
.then((resp) => {
if (resp.ok) {
return resp.json();
}
throw new Error(resp.statusText);
});

return [];
}

/**
@@ -110,7 +90,7 @@ class TermsService {
return Promise.resolve(term);
}
// Otherwise grab new details from terms api
return this.getTermDetails(term.termsOfUseId).then(res => _.pick(res, ['termsOfUseId', 'agreed', 'title']));
return this.getTermDetails(term.id).then(res => _.pick(res, ['id', 'agreed', 'title']));
});

return Promise.all(promises).then(terms => ({ terms }));
@@ -123,8 +103,7 @@ class TermsService {
*/
getTermDetails(termId) {
// looks like server cache responses, to prevent it we add nocache param with always new value
const nocache = (new Date()).getTime();
return this.private.api.get(`/terms/detail/${termId}?nocache=${nocache}`)
return this.private.api.get(`/terms/${termId}`)
.then(res => (res.ok ? res.json() : Promise.reject(res.json())));
}

@@ -135,7 +114,11 @@ class TermsService {
* @return {Promise} promise of the request result
*/
getDocuSignUrl(templateId, returnUrl) {
return this.private.api.post(`/terms/docusign/viewURL?templateId=${templateId}&returnUrl=${returnUrl}`)
const params = {
templateId,
returnUrl,
};
return this.private.api.postJson('/terms/docusignViewURL', params)
.then(res => (res.ok ? res.json() : Promise.reject(res.json())));
}

@@ -153,20 +136,20 @@ class TermsService {
let lastInstance = null;
/**
* Returns a new or existing terms service.
* @param {String} tokenV2 Optional. Auth token for Topcoder API v2.
* @param {String} tokenV3 Optional. Auth token for Topcoder API v3.
* @return {TermsService} Terms service object
*/
export function getService(tokenV2) {
export function getService(tokenV3) {
/* Because of Topcoder backend restrictions, it is not straightforward to test
* terms-related functionality in any other way than just providing an option
* to run the app against mock terms service. */
if (config.MOCK_TERMS_SERVICE) {
/* eslint-disable global-require */
return require('./__mocks__/terms').getService(tokenV2);
return require('./__mocks__/terms').getService(tokenV3);
/* eslint-enable global-require */
}
if (!lastInstance || (tokenV2 && lastInstance.private.tokenV2 !== tokenV2)) {
lastInstance = new TermsService(tokenV2);
if (!lastInstance || (tokenV3 && lastInstance.private.tokenV3 !== tokenV3)) {
lastInstance = new TermsService(tokenV3);
}
return lastInstance;
}