diff --git a/app/services/challenge.service.js b/app/services/challenge.service.js index 8e4fe5c08..eba8c1a3b 100644 --- a/app/services/challenge.service.js +++ b/app/services/challenge.service.js @@ -168,8 +168,8 @@ function processPastSRM(challenge) { if (Array.isArray(challenge.rounds) && challenge.rounds.length && challenge.rounds[0].userSRMDetails) { - challenge.newRating = challenge.rounds[0].userMMDetails.newRating; - challenge.pointTotal = challenge.rounds[0].userMMDetails.pointTotal; + challenge.newRating = challenge.rounds[0].userSRMDetails.newRating; + challenge.finalPoints = challenge.rounds[0].userSRMDetails.finalPoints; } } @@ -180,10 +180,6 @@ // process placement for challenges having winningPlacements array in response if (Array.isArray(challenge.userDetails.winningPlacements)) { challenge.highestPlacement = _.min(challenge.userDetails.winningPlacements); - challenge.wonFirst = challenge.highestPlacement == 1; - if (challenge.highestPlacement === 0) { - challenge.highestPlacement = null; - } } // process placement for design challenges if (challenge.track == 'DESIGN' && challenge.userDetails.submissions && challenge.userDetails.submissions.length > 0) { @@ -192,11 +188,17 @@ challenge.highestPlacement = _.min(challenge.userDetails.submissions.filter(function(submission) { return submission.type === CONSTANTS.SUBMISSION_TYPE_CONTEST && submission.placement; }), 'placement').placement; - - if (challenge.highestPlacement == 1) { - challenge.wonFirst = true; - } } + if (challenge.track === 'DEVELOP' && challenge.subTrack === 'FIRST_2_FINISH') { + challenge.highestPlacement = _.min(challenge.userDetails.submissions.filter(function(submission) { + return submission.type === CONSTANTS.SUBMISSION_TYPE_CONTEST + && submission.status === CONSTANTS.STATUS_ACTIVE && submission.placement; + }), 'placement').placement; + } + if (challenge.highestPlacement === 0) { + challenge.highestPlacement = null; + } + challenge.wonFirst = challenge.highestPlacement == 1; challenge.userHasSubmitterRole = false; diff --git a/app/services/challenge.service.spec.js b/app/services/challenge.service.spec.js index b0b6b5594..142dd8786 100644 --- a/app/services/challenge.service.spec.js +++ b/app/services/challenge.service.spec.js @@ -40,4 +40,476 @@ describe('Challenge Service', function() { $httpBackend.flush(); }); + it('processPastChallenges should process the won DESIGN/WEB_DESIGNS challenge ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DESIGN', + subTrack: 'WEB_DESIGNS', + userDetails: { + hasUserSubmittedForReview: true, + roles: ['Submitter'], + submissions: [ + { + challengeId: 30041345, + id: 12345, + placement: 1, + score: 98.0, + status: 'Active', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12346, + placement: 11, + score: 0.0, + status: 'Failed Review', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12347, + placement: 21, + score: 0.0, + status: 'Completed Without Win', + type: 'Checkpoint Submission' + } + ] + } + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).to.exist.to.equal(1); + expect(challenge.wonFirst).to.exist.to.true; + expect(challenge.userStatus).to.exist.to.equal('PASSED_REVIEW'); + expect(challenge.userHasSubmitterRole).to.exist.to.true; + }); + + it('processPastChallenges should process the won DEVELOP/ challenge ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'CODE', + userDetails: { + hasUserSubmittedForReview: true, + roles: ['Submitter'], + submissions: [ + { + challengeId: 30041345, + id: 12345, + placement: 1, + score: 98.0, + status: 'Active', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12346, + placement: 11, + score: 0.0, + status: 'Failed Review', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12347, + placement: 21, + score: 0.0, + status: 'Completed Without Win', + type: 'Checkpoint Submission' + } + ], + winningPlacements: [2, 11, 1] + } + + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).to.exist.to.equal(1); + expect(challenge.wonFirst).to.exist.to.true; + expect(challenge.userStatus).to.exist.to.equal('PASSED_REVIEW'); + expect(challenge.userHasSubmitterRole).to.exist.to.true; + }); + + it('processPastChallenges should process the lost DEVELOP/ challenge ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'CODE', + userDetails: { + hasUserSubmittedForReview: true, + roles: ['Submitter'], + submissions: [ + { + challengeId: 30041345, + id: 12345, + placement: 1, + score: 98.0, + status: 'Active', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12346, + placement: 11, + score: 0.0, + status: 'Failed Review', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12347, + placement: 21, + score: 0.0, + status: 'Completed Without Win', + type: 'Checkpoint Submission' + } + ], + winningPlacements: [0] + } + + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).not.to.exist; + expect(challenge.wonFirst).to.exist.to.false; + expect(challenge.userStatus).to.exist.to.equal('PASSED_SCREENING'); + expect(challenge.userHasSubmitterRole).to.exist.to.true; + }); + + it('processPastChallenges should process the won DEVELOP/FIRST_2_FINISH challenge ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'FIRST_2_FINISH', + userDetails: { + hasUserSubmittedForReview: true, + roles: ['Submitter'], + submissions: [ + { + challengeId: 30041345, + id: 12345, + placement: 1, + score: 98.0, + status: 'Active', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12346, + placement: 11, + score: 0.0, + status: 'Failed Review', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12347, + placement: 21, + score: 0.0, + status: 'Completed Without Win', + type: 'Checkpoint Submission' + } + ] + } + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).to.exist.to.equal(1); + expect(challenge.wonFirst).to.exist.to.true; + expect(challenge.userStatus).to.exist.to.equal('PASSED_REVIEW'); + expect(challenge.userHasSubmitterRole).to.exist.to.true; + }); + + it('processPastChallenges should process the lost(without placement) DEVELOP/FIRST_2_FINISH challenge ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'FIRST_2_FINISH', + userDetails: { + hasUserSubmittedForReview: true, + roles: ['Submitter'], + submissions: [ + { + challengeId: 30041345, + id: 12345, + placement: null, + score: 34.0, + status: 'Active', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12346, + placement: null, + score: 0.0, + status: 'Failed Review', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12347, + placement: 1, + score: 0.0, + status: 'Completed Without Win', + type: 'Checkpoint Submission' + } + ] + } + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).not.to.exist; + expect(challenge.wonFirst).to.exist.to.false; + expect(challenge.userStatus).to.exist.to.equal('PASSED_SCREENING'); + expect(challenge.userHasSubmitterRole).to.exist.to.true; + }); + + it('processPastChallenges should process the lost(with placement) DEVELOP/FIRST_2_FINISH challenge ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'FIRST_2_FINISH', + userDetails: { + hasUserSubmittedForReview: true, + roles: ['Submitter'], + submissions: [ + { + challengeId: 30041345, + id: 12345, + placement: 5, + score: 34.0, + status: 'Active', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12346, + placement: null, + score: 0.0, + status: 'Failed Review', + type: 'Contest Submission' + }, + { + challengeId: 30041345, + id: 12347, + placement: 1, + score: 0.0, + status: 'Completed Without Win', + type: 'Checkpoint Submission' + } + ] + } + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).to.exist.to.equal(5); + expect(challenge.wonFirst).to.exist.to.false; + expect(challenge.userStatus).to.exist.to.equal('PASSED_REVIEW'); + expect(challenge.userHasSubmitterRole).to.exist.to.true; + }); + + it('processPastChallenges should process a not completed DEVELOP/FIRST_2_FINISH challenge ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'FIRST_2_FINISH', + userDetails: { + hasUserSubmittedForReview: false, + roles: ['Submitter'], + submissions: [] + } + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).not.to.exist; + expect(challenge.wonFirst).to.exist.to.false; + expect(challenge.userStatus).to.exist.to.equal('NOT_FINISHED'); + expect(challenge.userHasSubmitterRole).to.exist.to.true; + }); + + it('processPastChallenges should process a DEVELOP/FIRST_2_FINISH challenge for a non submitter user ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'FIRST_2_FINISH', + userDetails: { + hasUserSubmittedForReview: false, + roles: ['Observer'], + submissions: [] + } + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).not.to.exist; + expect(challenge.wonFirst).to.exist.to.false; + expect(challenge.userStatus).to.exist.to.equal('COMPLETED'); + expect(challenge.userHasSubmitterRole).to.exist.to.false; + }); + + it('processPastChallenges should process a DEVELOP/ challenge for a user without role ', function() { + var challenges = [ + { + id: 30041345, + name: 'Mock Challenge 1', + track: 'DEVELOP', + subTrack: 'FIRST_2_FINISH', + userDetails: { + hasUserSubmittedForReview: false, + roles: [], + submissions: [], + winningPlacements: [0] + } + } + ]; + ChallengeService.processPastChallenges(challenges); + var challenge = challenges[0]; + expect(challenge.highestPlacement).not.to.exist; + expect(challenge.wonFirst).to.exist.to.false; + expect(challenge.userStatus).to.exist.to.equal('COMPLETED'); + expect(challenge.userHasSubmitterRole).to.exist.to.false; + }); + + it('processPastSRM should process SRM with valid placement ', function() { + var srm = { + id: 4460, + name: "Holder", + status: "PAST", + track: "DATA_SCIENCE", + subTrack : "SRM", + startDate: "8/30/15 12:00 AM", + endDate: "8/30/15 12:00 AM", + rounds: [ + { + id: 12345, + forumId: 54321, + status: "PAST", + userSRMDetails: { + newRating: 678, + finalPoints: 226.45 + } + } + ] + }; + ChallengeService.processPastSRM(srm); + expect(srm.newRating).to.exist.to.equal(678); + expect(srm.finalPoints).to.exist.to.equal(226.45); + }); + + it('processPastSRM should process SRM without rounds gracefully ', function() { + var srm = { + id: 4460, + name: "Holder", + status: "PAST", + track: "DATA_SCIENCE", + subTrack : "SRM", + startDate: "8/30/15 12:00 AM", + endDate: "8/30/15 12:00 AM", + rounds: [] + }; + ChallengeService.processPastSRM(srm); + expect(srm.newRating).not.to.exist; + expect(srm.finalPoints).not.to.exist; + }); + + it('processPastMarathonMatch should process MM with valid placement ', function() { + var mm = { + id: 4460, + name: "Holder", + status: "PAST ", + track: "DATA_SCIENCE", + subTrack : "MARATHON_MATCH", + startDate: "8/30/15 12:00 AM", + endDate: "8/30/15 12:00 AM", + rounds: [ + { + id: 12345, + forumId: 54321, + status: "PAST", + systemTestEndAt: "8/29/15 12:00 AM", + userMMDetails: { + newRating: 678, + rated: true, + pointTotal: 22645 + } + } + ] + }; + ChallengeService.processPastMarathonMatch(mm); + expect(mm.status).to.exist.to.equal("PAST");// should trim the status + expect(mm.newRating).to.exist.to.equal(678); + expect(mm.pointTotal).to.exist.to.equal(22645); + expect(mm.submissionEndDate).to.exist.to.equal("8/29/15 12:00 AM"); + }); + + it('processPastMarathonMatch should process MM without rounds gracefully ', function() { + var mm = { + id: 4460, + name: "Holder", + status: "PAST", + track: "DATA_SCIENCE", + subTrack : "MARATHON_MATCH", + startDate: "8/30/15 12:00 AM", + endDate: "8/30/15 12:00 AM", + rounds: [] + }; + ChallengeService.processPastMarathonMatch(mm); + expect(mm.newRating).not.to.exist; + expect(mm.pointTotal).not.to.exist; + expect(mm.submissionEndDate).not.to.exist; + }); + + it('processPastMarathonMatch should process MM with unrated user details ', function() { + var mm = { + id: 4460, + name: "Holder", + status: "PAST ", + track: "DATA_SCIENCE", + subTrack : "MARATHON_MATCH", + startDate: "8/30/15 12:00 AM", + endDate: "8/30/15 12:00 AM", + rounds: [ + { + id: 12345, + forumId: 54321, + status: "PAST", + systemTestEndAt: "8/29/15 12:00 AM", + userMMDetails: { + newRating: null, + rated: false, + pointTotal: null + } + } + ] + }; + ChallengeService.processPastMarathonMatch(mm); + expect(mm.status).to.exist.to.equal("PAST");// should trim the status + expect(mm.newRating).not.to.exist; + expect(mm.pointTotal).not.to.exist; + expect(mm.submissionEndDate).not.to.exist; + }); + }); diff --git a/app/topcoder.constants.js b/app/topcoder.constants.js index 037784533..5aefe4381 100644 --- a/app/topcoder.constants.js +++ b/app/topcoder.constants.js @@ -33,7 +33,8 @@ angular.module("CONSTANTS", []) "REGISTRATION": "REGISTRATION", "CODING": "CODING", "REGISTERED": "REGISTERED", - "SUBMISSION_TYPE_CONTEST": "Contest Submission" + "SUBMISSION_TYPE_CONTEST": "Contest Submission", + "STATUS_ACTIVE": "Active" }) ; \ No newline at end of file diff --git a/config.js b/config.js index a4659bbe3..de6a19525 100644 --- a/config.js +++ b/config.js @@ -45,7 +45,10 @@ module.exports = function() { REGISTERED: 'REGISTERED', // submission type - SUBMISSION_TYPE_CONTEST: 'Contest Submission' + SUBMISSION_TYPE_CONTEST: 'Contest Submission', + + // statuses for different objects + STATUS_ACTIVE: 'Active' } }, @@ -94,7 +97,10 @@ module.exports = function() { REGISTERED: 'REGISTERED', // submission type - SUBMISSION_TYPE_CONTEST: 'Contest Submission' + SUBMISSION_TYPE_CONTEST: 'Contest Submission', + + // statuses for different objects + STATUS_ACTIVE: 'Active' } }, @@ -143,7 +149,10 @@ module.exports = function() { REGISTERED: 'REGISTERED', // submission type - SUBMISSION_TYPE_CONTEST: 'Contest Submission' + SUBMISSION_TYPE_CONTEST: 'Contest Submission', + + // statuses for different objects + STATUS_ACTIVE: 'Active' } }, @@ -192,7 +201,10 @@ module.exports = function() { REGISTERED: 'REGISTERED', // submission type - SUBMISSION_TYPE_CONTEST: 'Contest Submission' + SUBMISSION_TYPE_CONTEST: 'Contest Submission', + + // statuses for different objects + STATUS_ACTIVE: 'Active' } }, @@ -241,7 +253,10 @@ module.exports = function() { REGISTERED: 'REGISTERED', // submission type - SUBMISSION_TYPE_CONTEST: 'Contest Submission' + SUBMISSION_TYPE_CONTEST: 'Contest Submission', + + // statuses for different objects + STATUS_ACTIVE: 'Active' } }