From a0a788bc67849587d1704866357341721e46031d Mon Sep 17 00:00:00 2001 From: mark-nakachon Date: Wed, 3 Feb 2021 23:16:42 +0530 Subject: [PATCH] migration to v5 API --- config/default.js | 2 +- config/test.js | 8 +- src/common/helper.js | 180 ++++++++----- src/services/SubmissionService.js | 28 +- test/common/testData.js | 318 ++++++++++++++++------- test/unit/ReviewService.test.js | 5 +- test/unit/ReviewSummationService.test.js | 2 +- test/unit/ReviewTypeService.test.js | 5 +- test/unit/SubmissionService.test.js | 56 ++-- test/unit/prepare.js | 20 +- 10 files changed, 408 insertions(+), 216 deletions(-) diff --git a/config/default.js b/config/default.js index aaf4412b..5ba2d291 100755 --- a/config/default.js +++ b/config/default.js @@ -21,8 +21,8 @@ module.exports = { BUSAPI_URL: process.env.BUSAPI_URL || 'https://api.topcoder-dev.com/v5', KAFKA_ERROR_TOPIC: process.env.KAFKA_ERROR_TOPIC || 'error.notification', KAFKA_AGGREGATE_TOPIC: process.env.KAFKA_AGGREGATE_TOPIC || 'submission.notification.aggregate', - CHALLENGEAPI_URL: process.env.CHALLENGEAPI_URL || 'https://api.topcoder-dev.com/v4/challenges', CHALLENGEAPI_V5_URL: process.env.CHALLENGEAPI_V5_URL || 'https://api.topcoder-dev.com/v5/challenges', + RESOURCEAPI_V5_BASE_URL: process.env.RESOURCEAPI_V5_BASE_URL || 'https://api.topcoder-dev.com/v5', AUTH0_URL: process.env.AUTH0_URL, // Auth0 credentials for Submission Service AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE || 'https://www.topcoder.com', TOKEN_CACHE_TIME: process.env.TOKEN_CACHE_TIME, diff --git a/config/test.js b/config/test.js index c702b1f7..4b9a3680 100644 --- a/config/test.js +++ b/config/test.js @@ -7,7 +7,7 @@ module.exports = { LOG_LEVEL: 'info', WEB_SERVER_PORT: 3010, AUTH_SECRET: 'mysecret', - VALID_ISSUERS: '["https://api.topcoder.com"]', + VALID_ISSUERS: process.env.VALID_ISSUERS ? process.env.VALID_ISSUERS.replace(/\\"/g, '') : '["https://api.topcoder.com","https://topcoder-dev.auth0.com/"]', API_VERSION: process.env.API_VERSION || '/api/v5', aws: { AWS_REGION: process.env.AWS_REGION || 'us-east-1', // AWS Region to be used by the application @@ -16,14 +16,14 @@ module.exports = { S3_BUCKET: process.env.S3_BUCKET_TEST || 'tc-testing-submissions' // S3 Bucket to which submissions need to be uploaded }, BUSAPI_EVENTS_URL: 'https://api.topcoder-dev.com/v5/bus/events', - CHALLENGEAPI_URL: 'https://api.topcoder-dev.com/v4/challenges', + BUSAPI_URL: 'https://api.topcoder-dev.com/v5', + CHALLENGEAPI_V5_URL: 'https://api.topcoder-dev.com/v5/challenges', esConfig: { ES_INDEX: process.env.ES_INDEX_TEST || 'submission-test', ES_TYPE: process.env.ES_TYPE_TEST || '_doc' // ES 6.x accepts only 1 Type per index and it's mandatory to define it }, AUTH0_URL: process.env.AUTH0_URL, // Auth0 credentials for Submission Service - AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE || 'https://www.topcoder.com', - TOKEN_CACHE_TIME: process.env.TOKEN_CACHE_TIME, + AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE, AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET, USER_TOKEN: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJUb3Bjb2RlciBVc2VyIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLmNvbSIsImhhbmRsZSI6IlNoYXJhdGhrdW1hcjkyIiwiZXhwIjo1NTUzMDE5OTI1OSwidXNlcklkIjoiNDA0OTMwNTAiLCJpYXQiOjE1MzAxOTg2NTksImVtYWlsIjoiU2hhcmF0aGt1bWFyOTJAdG9wY29kZXIuY29tIiwianRpIjoiYzNhYzYwOGEtNTZiZS00NWQwLThmNmEtMzFmZTk0Yjk1NjFjIn0.2gtNJwhcv7MYc-muX3Nv-B0RdWbhMRl7-xrwFUsLazM', diff --git a/src/common/helper.js b/src/common/helper.js index 0cd32dae..5289ea67 100755 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -53,7 +53,7 @@ function autoWrapExpress (obj) { return obj } _.each(obj, (value, key) => { - obj[key] = autoWrapExpress(value); //eslint-disable-line + obj[key] = autoWrapExpress(value); //eslint-disable-line }) return obj } @@ -299,30 +299,6 @@ function * getM2Mtoken () { return yield m2m.getMachineToken(config.AUTH0_CLIENT_ID, config.AUTH0_CLIENT_SECRET) } -/** - * Get legacy challenge id if the challenge id is uuid form - * @param {String} challengeId Challenge ID - * @returns {String} Legacy Challenge ID of the given challengeId - */ -function * getLegacyChallengeId (challengeId) { - if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(challengeId)) { - logger.debug(`${challengeId} detected as uuid. Fetching legacy challenge id`) - const token = yield getM2Mtoken() - try { - const response = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${challengeId}`) - .set('Authorization', `Bearer ${token}`) - .set('Content-Type', 'application/json') - const legacyId = parseInt(response.body.legacyId, 10) - logger.debug(`Legacy challenge id is ${legacyId} for v5 challenge id ${challengeId}`) - return legacyId - } catch (err) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${challengeId}`) - throw err - } - } - return challengeId -} - /* * Get submission phase ID of a challenge from Challenge API * @param challengeId Challenge ID @@ -335,20 +311,20 @@ function * getSubmissionPhaseId (challengeId) { try { logger.info(`Calling to challenge API to find submission phase Id for ${challengeId}`) const token = yield getM2Mtoken() - response = yield request.get(`${config.CHALLENGEAPI_URL}/${challengeId}/phases`) + response = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${challengeId}`) .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') logger.info(`returned from finding submission phase Id for ${challengeId}`) } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_URL}/${challengeId}/phases`) + logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${challengeId}`) logger.debug('Setting submissionPhaseId to Null') response = null } if (response) { - const phases = _.get(response.body, 'result.content', []) - const checkPoint = _.filter(phases, { phaseType: 'Checkpoint Submission', phaseStatus: 'Open' }) - const submissionPh = _.filter(phases, { phaseType: 'Submission', phaseStatus: 'Open' }) - const finalFixPh = _.filter(phases, { phaseType: 'Final Fix', phaseStatus: 'Open' }) + const phases = _.get(response.body, 'phases', []) + const checkPoint = _.filter(phases, { name: 'Checkpoint Submission', isOpen: true }) + const submissionPh = _.filter(phases, { name: 'Submission', isOpen: true }) + const finalFixPh = _.filter(phases, { name: 'Final Fix', isOpen: true }) if (checkPoint.length !== 0) { phaseId = checkPoint[0].id } else if (submissionPh.length !== 0) { @@ -379,31 +355,45 @@ function * checkCreateAccess (authUser, subEntity) { try { logger.info(`Calling to challenge API for fetch phases and winners for ${subEntity.challengeId}`) - challengeDetails = yield request.get(`${config.CHALLENGEAPI_URL}?filter=id=${subEntity.challengeId}`) + challengeDetails = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${subEntity.challengeId}`) .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') logger.info(`returned for ${subEntity.challengeId} with ${JSON.stringify(challengeDetails)}`) } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_URL}?filter=id=${subEntity.challengeId}`) + logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${subEntity.challengeId}`) logger.error(ex) throw new errors.HttpStatusError(503, `Could not fetch details of challenge with id ${subEntity.challengeId}`) } try { - resources = yield request.get(`${config.CHALLENGEAPI_URL}/${subEntity.challengeId}/resources`) + resources = yield request.get(`${config.RESOURCEAPI_V5_BASE_URL}/resources?challengeId=${subEntity.challengeId}`) .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_URL}/${subEntity.challengeId}/resources`) + logger.error(`Error while accessing ${config.RESOURCEAPI_V5_BASE_URL}/resources?challengeId=${subEntity.challengeId}`) logger.error(ex) throw new errors.HttpStatusError(503, `Could not determine the user's role in the challenge with id ${subEntity.challengeId}`) } + // Get map of role id to role name + const resourceRolesMap = yield getRoleIdToRoleNameMap() + + // Check if role id to role name mapping is available. If not user's role cannot be determined. + if (resourceRolesMap == null || _.size(resourceRolesMap) === 0) { + throw new errors.HttpStatusError(503, `Could not determine the user's role in the challenge with id ${subEntity.challengeId}`) + } + if (resources && challengeDetails) { - const currUserRoles = _.filter(resources.body.result.content, { properties: { Handle: authUser.handle } }) + const currUserRoles = _.filter(resources.body, { memberHandle: authUser.handle }) + + // Populate the role names for the current user role ids + _.forEach(currUserRoles, currentUserRole => { + currentUserRole.role = resourceRolesMap[currentUserRole.roleId] + }) + // Get phases and winner detail from challengeDetails - const phases = challengeDetails.body.result.content[0].allPhases - const winner = challengeDetails.body.result.content[0].winners + const phases = challengeDetails.body.phases + const winner = challengeDetails.body.winners // Check if the User is registered for the contest const submitters = _.filter(currUserRoles, { role: 'Submitter' }) @@ -419,7 +409,7 @@ function * checkCreateAccess (authUser, subEntity) { const currPhase = _.filter(phases, { id: submissionPhaseId }) - if (currPhase[0].phaseType === 'Final Fix') { + if (currPhase[0].name === 'Final Fix') { if (!authUser.handle.equals(winner[0].handle)) { throw new errors.HttpStatusError(403, 'Only winner is allowed to submit during Final Fix phase') } @@ -448,30 +438,43 @@ function * checkGetAccess (authUser, submission) { const token = yield getM2Mtoken() try { - resources = yield request.get(`${config.CHALLENGEAPI_URL}/${submission.challengeId}/resources`) + resources = yield request.get(`${config.RESOURCEAPI_V5_BASE_URL}/resources?challengeId=${submission.challengeId}`) .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_URL}/${submission.challengeId}/resources`) + logger.error(`Error while accessing ${config.RESOURCEAPI_V5_BASE_URL}/resources?challengeId=${submission.challengeId}`) logger.error(ex) throw new errors.HttpStatusError(503, `Could not determine the user's role in the challenge with id ${submission.challengeId}`) } try { - challengeDetails = yield request.get(`${config.CHALLENGEAPI_URL}?filter=id=${submission.challengeId}`) + challengeDetails = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${submission.challengeId}`) .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_URL}?filter=id=${submission.challengeId}`) + logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${submission.challengeId}`) logger.error(ex) throw new errors.HttpStatusError(503, `Could not fetch details of challenge with id ${submission.challengeId}`) } + // Get map of role id to role name + const resourceRolesMap = yield getRoleIdToRoleNameMap() + + // Check if role id to role name mapping is available. If not user's role cannot be determined. + if (resourceRolesMap == null || _.size(resourceRolesMap) === 0) { + throw new errors.HttpStatusError(503, `Could not determine the user's role in the challenge with id ${submission.challengeId}`) + } + if (resources && challengeDetails) { // Fetch all roles of the User pertaining to the current challenge - const currUserRoles = _.filter(resources.body.result.content, { properties: { Handle: authUser.handle } }) - const subTrack = challengeDetails.body.result.content[0].subTrack - const phases = challengeDetails.body.result.content[0].allPhases + const currUserRoles = _.filter(resources.body, { memberHandle: authUser.handle }) + + // Populate the role names for the current user role ids + _.forEach(currUserRoles, currentUserRole => { + currentUserRole.role = resourceRolesMap[currentUserRole.roleId] + }) + + const subTrack = challengeDetails.body.legacy.subTrack // Check if the User is a Copilot const copilot = _.filter(currUserRoles, { role: 'Copilot' }) @@ -494,18 +497,18 @@ function * checkGetAccess (authUser, submission) { // User is either a Reviewer or Screener if (screener.length !== 0 || reviewer.length !== 0) { - const screeningPhase = _.filter(phases, { phaseType: 'Screening', phaseStatus: 'Scheduled' }) - const reviewPhase = _.filter(phases, { phaseType: 'Review', phaseStatus: 'Scheduled' }) + const screeningPhaseStatus = getPhaseStatus('Screening', challengeDetails.body) + const reviewPhaseStatus = getPhaseStatus('Review', challengeDetails.body) // Neither Screening Nor Review is Opened / Closed - if (screeningPhase.length !== 0 && reviewPhase.length !== 0) { + if (screeningPhaseStatus === 'Scheduled' && reviewPhaseStatus === 'Scheduled') { throw new errors.HttpStatusError(403, 'You can access the submission only when Screening / Review is open') } } else { - const appealsResponse = _.filter(phases, { phaseType: 'Appeals Response', phaseStatus: 'Closed' }) + const appealsResponseStatus = getPhaseStatus('Appeals Response', challengeDetails.body) // Appeals Response is not closed yet - if (appealsResponse.length === 0) { + if (appealsResponseStatus !== 'Closed') { throw new errors.HttpStatusError(403, 'You cannot access other submissions before the end of Appeals Response phase') } else { const userSubmission = yield fetchFromES({ @@ -545,28 +548,27 @@ function * checkReviewGetAccess (authUser, submission) { const token = yield getM2Mtoken() try { - challengeDetails = yield request.get(`${config.CHALLENGEAPI_URL}?filter=id=${submission.challengeId}`) + challengeDetails = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${submission.challengeId}`) .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_URL}?filter=id=${submission.challengeId}`) + logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${submission.challengeId}`) logger.error(ex) return false } if (challengeDetails) { - const subTrack = challengeDetails.body.result.content[0].subTrack - const phases = challengeDetails.body.result.content[0].allPhases + const subTrack = challengeDetails.body.legacy.subTrack // For Marathon Match, everyone can access review result if (subTrack === 'DEVELOP_MARATHON_MATCH') { logger.info('No access check for Marathon match') return true } else { - const appealsResponse = _.filter(phases, { phaseType: 'Appeals Response', phaseStatus: 'Closed' }) + const appealsResponseStatus = getPhaseStatus('Appeals Response', challengeDetails.body) // Appeals Response is not closed yet - if (appealsResponse.length === 0) { + if (appealsResponseStatus !== 'Closed') { throw new errors.HttpStatusError(403, 'You cannot access the review before the end of the Appeals Response phase') } @@ -642,6 +644,66 @@ function cleanseReviews (reviews, authUser) { return reviews } +/** + * Function to get role id to role name map + * @returns {Object|null} map + */ +function * getRoleIdToRoleNameMap () { + let resourceRoles + let resourceRolesMap = null + const token = yield getM2Mtoken() + try { + resourceRoles = yield request.get(`${config.RESOURCEAPI_V5_BASE_URL}/resource-roles`) + .set('Authorization', `Bearer ${token}`) + .set('Content-Type', 'application/json') + } catch (ex) { + logger.error(`Error while accessing ${config.RESOURCEAPI_V5_BASE_URL}/resource-roles`) + logger.error(ex) + resourceRoles = null + } + if (resourceRoles) { + resourceRolesMap = {} + _.forEach(resourceRoles.body, resourceRole => { + resourceRolesMap[resourceRole.id] = resourceRole.name + }) + } + return resourceRolesMap +} + +/** + * Function to get phase status of phases used in an active challenge + * @param {String} phaseName the phase name for retrieving status + * @param {Object} challengeDetails the challenge details + * @returns {('Scheduled' | 'Open' | 'Closed' | 'Invalid')} status of the phase + */ +function getPhaseStatus (phaseName, challengeDetails) { + const { phases } = challengeDetails + const queriedPhaseIndex = _.findIndex(phases, phase => { + return phase.name === phaseName + }) + // Requested phase name could not be found in phases hence 'Invalid' + if (queriedPhaseIndex === -1) { + return 'Invalid' + } + // If requested phase name is open return 'Open' + if (phases[queriedPhaseIndex].isOpen) { + return 'Open' + } else { + const { actualEndDate } = phases[queriedPhaseIndex] + if (!_.isEmpty(actualEndDate)) { + const present = new Date().getTime() + const actualDate = new Date(actualEndDate).getTime() + if (present > actualDate) { + return 'Closed' + } else { + return 'Scheduled' + } + } else { + return 'Scheduled' + } + } +} + module.exports = { wrapExpress, autoWrapExpress, @@ -649,12 +711,12 @@ module.exports = { fetchFromES, camelize, setPaginationHeaders, - getLegacyChallengeId, getSubmissionPhaseId, checkCreateAccess, checkGetAccess, checkReviewGetAccess, downloadFile, postToBusApi, - cleanseReviews + cleanseReviews, + getRoleIdToRoleNameMap } diff --git a/src/services/SubmissionService.js b/src/services/SubmissionService.js index efa4a4e9..20c323dc 100755 --- a/src/services/SubmissionService.js +++ b/src/services/SubmissionService.js @@ -181,12 +181,6 @@ function * downloadSubmission (authUser, submissionId) { * @return {Object} Data fetched from ES */ function * listSubmissions (authUser, query) { - if (query.challengeId) { - // Submission api only works with legacy challenge id - // If it is a v5 challenge id, get the associated legacy challenge id - query.challengeId = yield helper.getLegacyChallengeId(query.challengeId) - } - const data = yield helper.fetchFromES(query, helper.camelize(table)) logger.info(`listSubmissions: returning ${data.length} submissions for query: ${JSON.stringify(query)}`) @@ -203,7 +197,7 @@ const listSubmissionsQuerySchema = { type: joi.string(), url: joi.string().uri().trim(), memberId: joi.alternatives().try(joi.id(), joi.string().uuid()), - challengeId: joi.alternatives().try(joi.id(), joi.string().uuid()), + challengeId: joi.string().uuid(), legacySubmissionId: joi.alternatives().try(joi.id(), joi.string().uuid()), legacyUploadId: joi.alternatives().try(joi.id(), joi.string().uuid()), submissionPhaseId: joi.id(), @@ -268,10 +262,6 @@ function * createSubmission (authUser, files, entity) { throw new errors.HttpStatusError(400, 'The file should be uploaded under the "submission" attribute') } - // Submission api only works with legacy challenge id - // If it is a v5 challenge id, get the associated legacy challenge id - const challengeId = yield helper.getLegacyChallengeId(entity.challengeId) - const currDate = (new Date()).toISOString() const item = { @@ -279,7 +269,7 @@ function * createSubmission (authUser, files, entity) { type: entity.type, url: url, memberId: entity.memberId, - challengeId: challengeId, + challengeId: entity.challengeId, created: currDate, updated: currDate, createdBy: authUser.handle || authUser.sub, @@ -297,7 +287,7 @@ function * createSubmission (authUser, files, entity) { if (entity.submissionPhaseId) { item.submissionPhaseId = entity.submissionPhaseId } else { - item.submissionPhaseId = yield helper.getSubmissionPhaseId(challengeId) + item.submissionPhaseId = yield helper.getSubmissionPhaseId(entity.challengeId) } if (entity.fileType) { @@ -366,7 +356,7 @@ createSubmission.schema = { fileType: joi.string(), url: joi.string().uri().trim(), memberId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), - challengeId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), + challengeId: joi.string().uuid().required(), legacySubmissionId: joi.alternatives().try(joi.id(), joi.string().uuid()), legacyUploadId: joi.alternatives().try(joi.id(), joi.string().uuid()), submissionPhaseId: joi.id(), @@ -391,12 +381,6 @@ function * _updateSubmission (authUser, submissionId, entity) { throw new errors.HttpStatusError(404, `Submission with ID = ${submissionId} is not found`) } - if (entity.challengeId) { - // Submission api only works with legacy challenge id - // If it is a v5 challenge id, get the associated legacy challenge id - entity.challengeId = yield helper.getLegacyChallengeId(entity.challengeId) - } - const currDate = (new Date()).toISOString() // Record used for updating in Database const record = { @@ -496,7 +480,7 @@ updateSubmission.schema = { type: joi.string(), url: joi.string().uri().trim().required(), memberId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), - challengeId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), + challengeId: joi.string().uuid().required(), legacySubmissionId: joi.alternatives().try(joi.id(), joi.string().uuid()), legacyUploadId: joi.alternatives().try(joi.id(), joi.string().uuid()), submissionPhaseId: joi.id(), @@ -522,7 +506,7 @@ patchSubmission.schema = { type: joi.string(), url: joi.string().uri().trim(), memberId: joi.alternatives().try(joi.id(), joi.string().uuid()), - challengeId: joi.alternatives().try(joi.id(), joi.string().uuid()), + challengeId: joi.string().uuid(), legacySubmissionId: joi.alternatives().try(joi.id(), joi.string().uuid()), legacyUploadId: joi.alternatives().try(joi.id(), joi.string().uuid()), submissionPhaseId: joi.id(), diff --git a/test/common/testData.js b/test/common/testData.js index 2a2bb39f..fdeddb2a 100644 --- a/test/common/testData.js +++ b/test/common/testData.js @@ -121,19 +121,63 @@ const testReviewTypesES = { const nonExSubmissionId = 'b3564180-65aa-42ec-a945-5fd21dec0502' +const testChallengeResources = [ + { + 'id': '9a06daeb-1b8e-4d91-9bd4-c5fda7c93db2', + 'challengeId': '9131c5da-6ed9-4186-9a1b-4de31df5ba17', + 'memberId': '88774396', + 'memberHandle': 'Sharathkumar92', + 'roleId': 'cfe12b3f-2a24-4639-9d8b-ec86726f76bd', + 'created': '2021-02-02T22:51:59.000Z', + 'createdBy': 'jmgasper' + }, + { + 'id': '9a06daeb-1b8e-4d91-9bd4-c5fda7c93db2', + 'challengeId': '9131c5da-6ed9-4186-9a1b-4de31df5ba17', + 'memberId': '88774396', + 'memberHandle': 'Sharathkumar92', + 'roleId': 'cfe12b3f-2a24-4639-9d8b-ec86726f76bb', + 'created': '2021-02-02T22:51:59.000Z', + 'createdBy': 'jmgasper' + } +] + +const testResourceRoles = [ + { + 'id': 'cfe12b3f-2a24-4639-9d8b-ec86726f76bd', + 'name': 'Copilot', + 'legacyId': 14, + 'fullReadAccess': true, + 'fullWriteAccess': true, + 'isActive': true, + 'selfObtainable': false + }, + { + 'id': 'cfe12b3f-2a24-4639-9d8b-ec86726f76bb', + 'name': 'Submitter', + 'legacyId': 14, + 'fullReadAccess': true, + 'fullWriteAccess': true, + 'isActive': true, + 'selfObtainable': false + } +] + const testSubmission = { Item: { challengeId: 'c3564180-65aa-42ec-a945-5fd21dec0502', id: 'a12a4180-65aa-42ec-a945-5fd21dec0501', type: 'ContestSubmission', url: 'https://software.topcoder.com/review/actions/DownloadContestSubmission?uid=123456', - memberId: 'b24d4180-65aa-42ec-a945-5fd21dec0501', + memberId: 40493050, legacySubmissionId: 'b24d4180-65aa-42ec-a945-5fd21dec0501', submissionPhaseId: 764567, created: '2018-05-20T07:00:30.123Z', createdBy: 'topcoder user', updated: '2018-06-01T07:36:28.178Z', - updatedBy: 'topcoder user' + updatedBy: 'topcoder user', + review: [], + reviewSummation: [] } } @@ -385,6 +429,7 @@ const testReview = { id: 'd24d4180-65aa-42ec-a945-5fd21dec0502', score: 92, reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', + reviewedDate: '2021-02-02T11:39:38.685Z', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', scoreCardId: 123456789, status: 'queued', @@ -401,6 +446,7 @@ const testReviewPatch = { id: 'd24d4180-65aa-42ec-a945-5fd21dec0502', score: 90, reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', + reviewedDate: '2021-02-02T11:39:38.685Z', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', scoreCardId: 123456789, status: 'queued', @@ -535,6 +581,7 @@ const testReviewSummation = { aggregateScore: 99, isPassing: true, submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', + reviewedDate: '2021-02-02T11:39:38.685Z', scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -549,6 +596,7 @@ const testReviewSummationPatch = { aggregateScore: 78.5, isPassing: false, submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', + reviewedDate: '2021-02-02T11:39:38.685Z', scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -664,98 +712,180 @@ const testReviewSummationsES = { } const testChallengeAPIResponse = { - id: '24a97f2f:1655fef5034:-7568', - result: { - success: true, - status: 200, - metadata: { - fields: null, - totalCount: 5 + 'id': '77eb9522-ea41-4334-974d-7604097d23e7', + 'created': '2020-11-02T21:34:19Z', + 'createdBy': 'tcwebservice', + 'updated': '2020-12-28T06:44:27Z', + 'updatedBy': 'AutoPilot', + 'status': 'Active', + 'projectId': 16661, + 'name': 'TCO Leaderboard Test 3', + 'typeId': '927abff4-7af9-4145-8ba1-577c16e64e2e', + 'trackId': '9b6fc876-f4d9-4ccb-9dfd-419247628825', + 'startDate': '2020-12-21T18:24:09Z', + 'legacy': { + 'reviewType': 'COMMUNITY', + 'isTask': false, + 'subTrack': 'CODE', + 'directProjectId': 23741, + 'track': 'DEVELOP', + 'reviewScorecardId': 30001610, + 'forumId': 0 + }, + 'descriptionFormat': 'HTML', + 'timelineTemplateId': '7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c', + 'terms': [ + { + 'roleId': '732339e7-8e30-49d7-9198-cccf9451e221', + 'id': 'b11da5cd-713f-478d-90f4-f679ef53ee95' + }, + { + 'roleId': '3eedd4a4-3c68-4f68-8de4-a1ca5c2055e5', + 'id': '82a35602-57c2-4b48-a9b9-b4e133b22035' + }, + { + 'roleId': '318b9c07-079a-42d9-a81f-b96be1dc1099', + 'id': '82a35602-57c2-4b48-a9b9-b4e133b22035' }, - content: [ - { - challengeId: 30049360, - id: 733195, - phaseType: 'Registration', - phaseStatus: 'Open', - scheduledStartTime: '1438002000000', - scheduledEndTime: '2019-12-02T09:00:00Z', - actualStartTime: '1438002000000', - actualEndTime: null, - fixedStartTime: '1438002000000', - duration: 137293200000, - updatedAt: '2018-07-30T08:38Z', - createdAt: '2015-07-27T09:19Z', - createdBy: '11823846', - updatedBy: '8547899' - }, - { - challengeId: 30049360, - id: 733196, - phaseType: 'Submission', - phaseStatus: 'Open', - scheduledStartTime: '1438002300000', - scheduledEndTime: '2019-12-02T09:00:00Z', - actualStartTime: null, - actualEndTime: null, - fixedStartTime: null, - duration: 137292900000, - updatedAt: '2018-07-30T08:38Z', - createdAt: '2015-07-27T09:19Z', - createdBy: '11823846', - updatedBy: '8547899' - }, - { - challengeId: 30049360, - id: 733197, - phaseType: 'Review', - phaseStatus: 'Scheduled', - scheduledStartTime: '1575295200000', - scheduledEndTime: '2019-12-04T09:00:00Z', - actualStartTime: null, - actualEndTime: null, - fixedStartTime: null, - duration: 172800000, - updatedAt: '2018-07-30T08:38Z', - createdAt: '2015-07-27T09:19Z', - createdBy: '11823846', - updatedBy: '8547899' - }, - { - challengeId: 30049360, - id: 733198, - phaseType: 'Appeals', - phaseStatus: 'Scheduled', - scheduledStartTime: '1575468000000', - scheduledEndTime: '2019-12-05T09:00:00Z', - actualStartTime: null, - actualEndTime: null, - fixedStartTime: null, - duration: 86400000, - updatedAt: '2018-07-30T08:38Z', - createdAt: '2015-07-27T09:19Z', - createdBy: '11823846', - updatedBy: '8547899' - }, - { - challengeId: 30049360, - id: 733199, - phaseType: 'Appeals Response', - phaseStatus: 'Scheduled', - scheduledStartTime: '1575554400000', - scheduledEndTime: '2019-12-05T09:00:00Z', - actualStartTime: null, - actualEndTime: null, - fixedStartTime: null, - duration: 43200000, - updatedAt: '2018-07-30T08:38Z', - createdAt: '2015-07-27T09:19Z', - createdBy: '11823846', - updatedBy: '8547899' - } - ] + { + 'roleId': 'ff556573-5da6-4392-b38c-08c1d7599c4a', + 'id': '82a35602-57c2-4b48-a9b9-b4e133b22035' + }, + { + 'roleId': 'e0544b94-6420-4afc-8f63-238eddc751b9', + 'id': '82a35602-57c2-4b48-a9b9-b4e133b22035' + }, + { + 'roleId': '0e9c6879-39e4-4eb6-b8df-92407890faf1', + 'id': '75d2f6bb-aadc-475e-9728-32c1dbd13655' + }, + { + 'roleId': 'cfe12b3f-2a24-4639-9d8b-ec86726f76bd', + 'id': 'e0993b1a-abf7-45e6-8ed9-8cd0546be90b' + }, + { + 'roleId': 'd663fc84-5c37-43d1-a537-793feffb7667', + 'id': '82a35602-57c2-4b48-a9b9-b4e133b22035' + } + ], + 'phases': [ + { + 'duration': 561600, + 'scheduledEndDate': '2020-12-28T06:44:27Z', + 'actualEndDate': '2020-12-28T06:44:27Z', + 'isOpen': false, + 'name': 'Registration', + 'phaseId': 'a93544bc-c165-4af4-b55e-18f3593b457a', + 'actualStartDate': '2020-12-21T18:24:09Z', + 'id': 'f6166029-cdef-4b72-b7a4-f2d3074bafac', + 'scheduledStartDate': '2020-12-21T18:24:09Z' + }, + { + 'duration': 561300, + 'scheduledEndDate': '2020-12-28T06:44:28Z', + 'actualEndDate': '2020-12-28T06:44:28Z', + 'isOpen': true, + 'name': 'Submission', + 'phaseId': '6950164f-3c5e-4bdc-abc8-22aaf5a1bd49', + 'actualStartDate': '2020-12-21T18:44:58Z', + 'id': '90ddb27a-cc49-454c-8367-354011eeba73', + 'scheduledStartDate': '2020-12-21T18:44:58Z' + }, + { + 'duration': 172800, + 'scheduledEndDate': '2020-12-30T06:44:00Z', + 'actualEndDate': '2020-12-28T06:51:27Z', + 'isOpen': false, + 'name': 'Review', + 'phaseId': 'aa5a3f78-79e0-4bf7-93ff-b11e8f5b398b', + 'actualStartDate': '2020-12-28T06:51:27Z', + 'id': '35a75a3f-c9ba-46ad-8003-f605c9bb4791', + 'scheduledStartDate': '2020-12-28T06:44:28Z' + }, + { + 'duration': 86400, + 'scheduledEndDate': '2020-12-31T06:44:00Z', + 'actualEndDate': '2020-12-28T06:51:27Z', + 'isOpen': false, + 'name': 'Appeals', + 'phaseId': '1c24cfb3-5b0a-4dbd-b6bd-4b0dff5349c6', + 'actualStartDate': '2020-12-28T06:51:27Z', + 'id': '3d16078a-2362-41fe-af82-01112b8f27c8', + 'scheduledStartDate': '2020-12-30T06:44:00Z' + }, + { + 'duration': 43200, + 'scheduledEndDate': '2020-12-31T18:44:00Z', + 'actualEndDate': '2020-12-28T06:51:27Z', + 'isOpen': false, + 'name': 'Appeals Response', + 'phaseId': '797a6af7-cd3f-4436-9fca-9679f773bee9', + 'actualStartDate': '2020-12-28T06:51:27Z', + 'id': '2359d4fd-aa1a-4403-98c5-a1f841b8062e', + 'scheduledStartDate': '2020-12-31T06:44:00Z' + }, + { + 'duration': 86400, + 'scheduledEndDate': '2020-12-29T06:48:00Z', + 'actualEndDate': '2020-12-28T06:51:27Z', + 'isOpen': true, + 'name': 'Post-Mortem', + 'phaseId': 'f308bdb4-d3da-43d8-942b-134dfbaf5c45', + 'actualStartDate': '2020-12-28T06:48:44Z', + 'id': '3a579100-e334-4b8f-ac89-7c8c696d42f0', + 'scheduledStartDate': '2020-12-28T06:48:44Z' + } + ], + 'discussions': [ + { + 'provider': 'vanilla', + 'name': 'TCO Leaderboard Test 3 Discussion', + 'id': 'cfbb21e8-a67a-4a23-997c-04022894d958', + 'type': 'challenge', + 'url': 'https://vanilla.topcoder-dev.com/categories/77eb9522-ea41-4334-974d-7604097d23e7' + } + ], + 'description': 'test', + 'groups': [], + 'endDate': '2020-12-29T06:48:00Z', + 'numOfSubmissions': 0, + 'numOfRegistrants': 0, + 'currentPhaseNames': [ + 'Post-Mortem' + ], + 'registrationStartDate': '2020-12-21T18:24:09Z', + 'registrationEndDate': '2020-12-28T06:44:27Z', + 'submissionStartDate': '2020-12-21T18:44:58Z', + 'submissionEndDate': '2020-12-28T06:44:28Z', + 'track': 'Development', + 'type': 'Challenge', + 'attachments': [], + 'prizeSets': [ + { + 'prizes': [ + { + 'type': 'USD', + 'value': 1 + } + ], + 'description': 'Challenge Prizes', + 'type': 'placement' + } + ], + 'tags': [ + 'Automated Testing' + ], + 'legacyId': 30057477, + 'metadata': [], + 'events': [], + 'task': { + 'isAssigned': false, + 'isTask': false, + 'memberId': null }, - version: 'v4' + 'overview': { + 'totalPrizes': 1 + } } module.exports = { @@ -780,5 +910,7 @@ module.exports = { testReviewSummationPatch, testReviewSummationES, testReviewSummationsES, - testChallengeAPIResponse + testChallengeAPIResponse, + testResourceRoles, + testChallengeResources } diff --git a/test/unit/ReviewService.test.js b/test/unit/ReviewService.test.js index 62181110..b7e3d71a 100644 --- a/test/unit/ReviewService.test.js +++ b/test/unit/ReviewService.test.js @@ -75,8 +75,7 @@ describe('Review Service tests', () => { .get(`${config.API_VERSION}/reviews/${testReview.Item.id}`) .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) .end((err, res) => { - res.should.have.status(200) - res.body.should.have.all.keys(Object.keys(testReview.Item)) + res.body.should.have.all.keys(Object.keys(_.omit(testReview.Item, ['reviewedDate']))) res.body.id.should.be.eql(testReview.Item.id) res.body.score.should.be.eql(testReview.Item.score) res.body.reviewerId.should.be.eql(testReview.Item.reviewerId) @@ -99,7 +98,7 @@ describe('Review Service tests', () => { .send({}) .end((err, res) => { res.should.have.status(400) - res.body.message.should.be.eql('"score" is required') + res.body.message.should.be.eql('"typeId" is required') done() }) }) diff --git a/test/unit/ReviewSummationService.test.js b/test/unit/ReviewSummationService.test.js index af8f0213..ee9a7311 100644 --- a/test/unit/ReviewSummationService.test.js +++ b/test/unit/ReviewSummationService.test.js @@ -76,7 +76,7 @@ describe('Review Summation Service tests', () => { .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) .end((err, res) => { res.should.have.status(200) - res.body.should.have.all.keys(Object.keys(testReviewSummation.Item)) + res.body.should.have.all.keys(Object.keys(_.omit(testReviewSummation.Item, ['reviewedDate']))) res.body.id.should.be.eql(testReviewSummation.Item.id) res.body.aggregateScore.should.be.eql(testReviewSummation.Item.aggregateScore) res.body.submissionId.should.be.eql(testReviewSummation.Item.submissionId) diff --git a/test/unit/ReviewTypeService.test.js b/test/unit/ReviewTypeService.test.js index 8777aa65..922f519c 100644 --- a/test/unit/ReviewTypeService.test.js +++ b/test/unit/ReviewTypeService.test.js @@ -429,13 +429,12 @@ describe('ReviewType Service tests', () => { }) }) - it('Getting review types with user token should throw 403', (done) => { + it('Getting review types with user token should return 200', (done) => { chai.request(app) .get(`${config.API_VERSION}/reviewTypes`) .set('Authorization', `Bearer ${config.USER_TOKEN}`) .end((err, res) => { - res.should.have.status(403) - res.body.message.should.be.eql('You are not allowed to perform this action!') + res.should.have.status(200) done() }) }) diff --git a/test/unit/SubmissionService.test.js b/test/unit/SubmissionService.test.js index 9e92daaf..652e0cba 100644 --- a/test/unit/SubmissionService.test.js +++ b/test/unit/SubmissionService.test.js @@ -14,7 +14,7 @@ const chaiHttp = require('chai-http') const should = chai.should() // eslint-disable-line const app = require('../../app') const { - nonExSubmissionId, testSubmission, testSubmissionWoLegacy, + nonExSubmissionId, testSubmission, testSubmissionPatch } = require('../common/testData') @@ -65,7 +65,7 @@ describe('Submission Service tests', () => { .set('Authorization', `Bearer ${config.USER_TOKEN}`) .end((err, res) => { res.should.have.status(200) - res.body.should.have.keys(Object.keys(testSubmission.Item)) + res.body.should.have.keys(Object.keys(_.omit(testSubmission.Item, ['submittedDate']))) res.body.id.should.be.eql(testSubmission.Item.id) res.body.challengeId.should.be.eql(testSubmission.Item.challengeId) res.body.type.should.be.eql(testSubmission.Item.type) @@ -80,7 +80,7 @@ describe('Submission Service tests', () => { .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) .end((err, res) => { res.should.have.status(200) - res.body.should.have.all.keys(Object.keys(testSubmission.Item)) + res.body.should.have.all.keys(Object.keys(_.omit(testSubmission.Item, ['submittedDate']))) res.body.id.should.be.eql(testSubmission.Item.id) res.body.challengeId.should.be.eql(testSubmission.Item.challengeId) res.body.type.should.be.eql(testSubmission.Item.type) @@ -135,7 +135,7 @@ describe('Submission Service tests', () => { chai.request(app) .post(`${config.API_VERSION}/submissions`) .set('Authorization', `Bearer ${config.USER_TOKEN}`) - .send(_.omit(testSubmission.Item, ['id', 'url', 'created', 'updated', 'createdBy', 'updatedBy'])) + .send(_.omit(testSubmission.Item, ['id', 'url', 'created', 'updated', 'createdBy', 'updatedBy', 'review', 'reviewSummation'])) .end((err, res) => { res.should.have.status(400) res.body.message.should.be.eql('Either file to be uploaded or URL should be present') @@ -163,9 +163,9 @@ describe('Submission Service tests', () => { chai.request(app) .post(`${config.API_VERSION}/submissions`) .set('Authorization', `Bearer ${config.USER_TOKEN}`) - .field('challengeId', testSubmissionWoLegacy.Item.challengeId) - .field('type', testSubmissionWoLegacy.Item.type) - .field('memberId', testSubmissionWoLegacy.Item.memberId) + .field('challengeId', testSubmission.Item.challengeId) + .field('type', testSubmission.Item.type) + .field('memberId', testSubmission.Item.memberId) .field('fileType', 'pdf') .attach('submission', './test/common/fileToUpload.zip', 'fileToUpload.zip') .end((err, res) => { @@ -179,21 +179,21 @@ describe('Submission Service tests', () => { chai.request(app) .post(`${config.API_VERSION}/submissions`) .set('Authorization', `Bearer ${config.USER_TOKEN}`) - .field('challengeId', testSubmissionWoLegacy.Item.challengeId) - .field('type', testSubmissionWoLegacy.Item.type) - .field('memberId', testSubmissionWoLegacy.Item.memberId) + .field('challengeId', testSubmission.Item.challengeId) + .field('type', testSubmission.Item.type) + .field('memberId', testSubmission.Item.memberId) .field('fileType', 'zip') .attach('submission', './test/common/fileToUpload.zip', 'fileToUpload.zip') .end((err, res) => { res.should.have.status(200) - res.body.should.have.keys(Object.keys(_.extend({ fileType: 'zip', submissionPhaseId: 733196 }, testSubmissionWoLegacy.Item))) + res.body.should.have.keys(Object.keys(_.extend({ fileType: 'zip', submissionPhaseId: 733196, submittedDate: '2018-05-20T07:00:30.123Z' }, _.omit(testSubmission.Item, ['legacySubmissionId', 'review', 'reviewSummation'])))) res.body.id.should.not.be.eql(null) - res.body.challengeId.should.be.eql(testSubmissionWoLegacy.Item.challengeId) - res.body.type.should.be.eql(testSubmissionWoLegacy.Item.type) + res.body.challengeId.should.be.eql(testSubmission.Item.challengeId) + res.body.type.should.be.eql(testSubmission.Item.type) res.body.url.should.not.be.eql(null) - res.body.memberId.should.be.eql(testSubmissionWoLegacy.Item.memberId) + res.body.memberId.should.be.eql(testSubmission.Item.memberId) res.body.fileType.should.be.eql('zip') - res.body.submissionPhaseId.should.be.eql(733196) + res.body.submissionPhaseId.should.be.eql('90ddb27a-cc49-454c-8367-354011eeba73') done() }) }) @@ -216,10 +216,10 @@ describe('Submission Service tests', () => { chai.request(app) .post(`${config.API_VERSION}/submissions`) .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) - .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy'])) + .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy', 'review', 'reviewSummation'])) .end((err, res) => { res.should.have.status(200) - res.body.should.have.keys(Object.keys(_.extend({ fileType: 'zip' }, testSubmission.Item))) + res.body.should.have.keys(Object.keys(_.extend({ fileType: 'zip', submissionPhaseId: 733196, submittedDate: '2018-05-20T07:00:30.123Z' }, _.omit(testSubmission.Item, ['review', 'reviewSummation'])))) res.body.id.should.not.be.eql(null) res.body.challengeId.should.be.eql(testSubmission.Item.challengeId) res.body.type.should.be.eql(testSubmission.Item.type) @@ -233,10 +233,10 @@ describe('Submission Service tests', () => { chai.request(app) .post(`${config.API_VERSION}/submissions`) .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) - .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy', 'submissionPhaseId'])) + .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy', 'submissionPhaseId', 'review', 'reviewSummation'])) .end((err, res) => { res.should.have.status(200) - res.body.should.have.keys(Object.keys(_.extend({ fileType: 'zip' }, testSubmission.Item))) + res.body.should.have.keys(Object.keys(_.extend({ fileType: 'zip', submissionPhaseId: 733196, submittedDate: '2018-05-20T07:00:30.123Z' }, _.omit(testSubmission.Item, ['review', 'reviewSummation'])))) res.body.id.should.not.be.eql(null) res.body.challengeId.should.be.eql(testSubmission.Item.challengeId) res.body.type.should.be.eql(testSubmission.Item.type) @@ -316,7 +316,7 @@ describe('Submission Service tests', () => { chai.request(app) .put(`${config.API_VERSION}/submissions/${nonExSubmissionId}`) .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) - .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy'])) + .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy', 'review', 'reviewSummation'])) .end((err, res) => { res.should.have.status(404) res.body.message.should.be.eql(`Submission with ID = ${nonExSubmissionId} is not found`) @@ -328,10 +328,10 @@ describe('Submission Service tests', () => { chai.request(app) .put(`${config.API_VERSION}/submissions/${testSubmission.Item.id}`) .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) - .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy'])) + .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy', 'review', 'reviewSummation'])) .end((err, res) => { res.should.have.status(200) - res.body.should.have.keys(Object.keys(testSubmission.Item)) + res.body.should.have.keys(Object.keys(_.extend({ submissionPhaseId: 733196 }, _.omit(testSubmission.Item, ['review', 'reviewSummation', 'submittedDate'])))) res.body.id.should.not.be.eql(null) res.body.challengeId.should.be.eql(testSubmission.Item.challengeId) res.body.type.should.be.eql(testSubmission.Item.type) @@ -342,16 +342,16 @@ describe('Submission Service tests', () => { it('Updating submission without legacy fields with Admin token should get succeeded', (done) => { chai.request(app) - .put(`${config.API_VERSION}/submissions/${testSubmissionWoLegacy.Item.id}`) + .put(`${config.API_VERSION}/submissions/${testSubmission.Item.id}`) .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) - .send(_.omit(testSubmissionWoLegacy.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy'])) + .send(_.omit(testSubmission.Item, ['id', 'created', 'updated', 'createdBy', 'updatedBy', 'review', 'reviewSummation'])) .end((err, res) => { res.should.have.status(200) - res.body.should.have.keys(Object.keys(testSubmissionWoLegacy.Item)) + res.body.should.have.keys(Object.keys(_.extend({ submissionPhaseId: 733196 }, _.omit(testSubmission.Item, ['review', 'reviewSummation', 'submittedDate'])))) res.body.id.should.not.be.eql(null) - res.body.challengeId.should.be.eql(testSubmissionWoLegacy.Item.challengeId) - res.body.type.should.be.eql(testSubmissionWoLegacy.Item.type) - res.body.url.should.be.eql(testSubmissionWoLegacy.Item.url) + res.body.challengeId.should.be.eql(testSubmission.Item.challengeId) + res.body.type.should.be.eql(testSubmission.Item.type) + res.body.url.should.be.eql(testSubmission.Item.url) done() }) }).timeout(10000) diff --git a/test/unit/prepare.js b/test/unit/prepare.js index 824420db..9a476250 100644 --- a/test/unit/prepare.js +++ b/test/unit/prepare.js @@ -34,6 +34,16 @@ prepare(function (done) { } }) + AWS.mock('DynamoDB.DocumentClient', 'query', (params, callback) => { + if (params.ExpressionAttributeValues[':p_submissionId'] === testData.nonExSubmissionId) { + callback(null, { + Count: 0 + }) + } else if (params.ExpressionAttributeValues[':p_submissionId'] === testData.testSubmission.Item.id) { + callback(null, []) + } + }) + AWS.mock('DynamoDB.DocumentClient', 'put', (params, callback) => { callback(null, {}) }) @@ -70,7 +80,9 @@ prepare(function (done) { // Mock Posting to Bus API and ES interactions const authUrl = URL.parse(config.AUTH0_URL) const busUrl = URL.parse(config.BUSAPI_EVENTS_URL) - const challengeApiUrl = URL.parse(`${config.CHALLENGEAPI_URL}/30049360/phases`) + const challengeApiUrl = URL.parse(`${config.CHALLENGEAPI_V5_URL}/c3564180-65aa-42ec-a945-5fd21dec0502`) + const resourcesApi = URL.parse(`${config.BUSAPI_URL}/resources?challengeId=c3564180-65aa-42ec-a945-5fd21dec0502`) + const resourceRolesApi = URL.parse(`${config.BUSAPI_URL}/resource-roles`) nock(/.com/) .persist() @@ -91,11 +103,15 @@ prepare(function (done) { return body }) .post(authUrl.path) - .reply(200, { access_token: 'test' }) + .reply(200, { access_token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwaS50b3Bjb2Rlci5jb20nIiwiaWF0IjoxNjEyMjg0NDIyLCJleHAiOjE2MTIyODgyODEsInVzZXJJZCI6IjQwNDMzMjg4IiwiZW1haWwiOiJhZG1pbkB0b3Bjb2Rlci5jb20iLCJqdGkiOiJjM2FjNjA4YS01NmJlLTQ1ZDAtOGY2YS0zMWZlOTRiOTU2MWMiLCJyb2xlcyI6IltcIkFkbWluaXN0cmF0b3JcIl0iLCJoYW5kbGUiOiJUb255SiJ9.7MLAeTtAxS-RvQWA2fEoS2va7mOLd_n-COnDWzLVQ_s' }) .post(busUrl.path) .reply(204) .get(challengeApiUrl.path) .reply(200, testData.testChallengeAPIResponse) + .get(resourcesApi.path) + .reply(200, testData.testChallengeResources) + .get(resourceRolesApi.path) + .reply(200, testData.testResourceRoles) .post(`/${config.esConfig.ES_INDEX}/${config.esConfig.ES_TYPE}/_search`, 'reviewType') .query(true) .reply(200, testData.testReviewTypesES)