diff --git a/src/actions/terms.js b/src/actions/terms.js index 136307df..599a9c79 100644 --- a/src/actions/terms.js +++ b/src/actions/terms.js @@ -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 })); } diff --git a/src/reducers/reviewOpportunity.js b/src/reducers/reviewOpportunity.js index 0bea4116..e1b8d5b8 100644 --- a/src/reducers/reviewOpportunity.js +++ b/src/reducers/reviewOpportunity.js @@ -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 || []; diff --git a/src/reducers/terms.js b/src/reducers/terms.js index b6bfdb49..d951643e 100644 --- a/src/reducers/terms.js +++ b/src/reducers/terms.js @@ -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 { diff --git a/src/services/terms.js b/src/services/terms.js index b34e62e1..a6914bbc 100644 --- a/src/services/terms.js +++ b/src/services/terms.js @@ -8,6 +8,7 @@ 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'; /** @@ -15,54 +16,33 @@ import { getApi } from './api'; */ 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} 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; }