From c0fc8503d09aff95776b280344ae0035f043cce6 Mon Sep 17 00:00:00 2001 From: Mithun Kamath Date: Sun, 18 Aug 2019 11:50:53 +0530 Subject: [PATCH 1/2] 1. Update Swagger to be in sync with the code #113 2. Provide sortyBy parameter when querying #124 3. Change which attribute is used to name artifacts in submissions #125 --- docs/Submission API.postman_collection.json | 251 ++++++++++++++++++- docs/submission-api.postman_environment.json | 13 +- docs/swagger.yaml | 166 ++++++++++-- package-lock.json | 12 +- scripts/data/ReviewSummations.json | 2 +- scripts/data/Reviews.json | 18 +- scripts/data/Submissions.json | 20 +- src/bootstrap.js | 2 +- src/common/helper.js | 28 ++- src/services/ArtifactService.js | 7 +- src/services/ReviewService.js | 36 ++- src/services/ReviewSummationService.js | 32 ++- src/services/ReviewTypeService.js | 20 +- src/services/SubmissionService.js | 48 ++-- test/common/testData.js | 28 +-- test/e2e/ReviewService.test.js | 11 + test/e2e/ReviewSummationService.test.js | 11 + test/e2e/ReviewTypeService.test.js | 11 + test/e2e/SubmissionService.test.js | 11 + test/unit/ReviewService.test.js | 11 + test/unit/ReviewSummationService.test.js | 11 + test/unit/ReviewTypeService.test.js | 11 + test/unit/SubmissionService.test.js | 11 + 23 files changed, 643 insertions(+), 128 deletions(-) diff --git a/docs/Submission API.postman_collection.json b/docs/Submission API.postman_collection.json index 83e199e3..973c8d8b 100755 --- a/docs/Submission API.postman_collection.json +++ b/docs/Submission API.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "9776607d-8485-4e67-bd2a-55e0b5100580", + "_postman_id": "567b1b26-0edf-4f9f-9f69-ed0b35f8422c", "name": "Submission API", "description": "Topcoder Submission API Postman Collection", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" @@ -410,6 +410,58 @@ }, "response": [] }, + { + "name": "GET Review types from ES with sortBy", + "event": [ + { + "listen": "test", + "script": { + "id": "290c7b35-fc15-468e-81a8-bd2a4eefcd27", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{ADMIN_TOKEN}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{URL}}/reviewTypes?sortBy=created&orderBy=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "reviewTypes" + ], + "query": [ + { + "key": "sortBy", + "value": "created" + }, + { + "key": "orderBy", + "value": "desc" + } + ] + } + }, + "response": [] + }, { "name": "GET Review types from ES with invalid filters", "event": [ @@ -749,13 +801,13 @@ "listen": "test", "script": { "id": "b0a4b893-f851-47bb-8b41-5dc60ba76fa0", - "type": "text/javascript", "exec": [ "if( responseCode.code === 200) {", " const response = JSON.parse(responseBody);", " pm.environment.set(\"reviewID\", response.id);", "}" - ] + ], + "type": "text/javascript" } } ], @@ -773,7 +825,7 @@ ], "body": { "mode": "raw", - "raw": "{\n\t\"score\": 92.5,\n\t\"scoreCardId\": \"d46a4180-65aa-42ec-a945-5fd21d3d26f8\",\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" + "raw": "{\n\t\"score\": 92.5,\n\t\"scoreCardId\": 123456789,\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" }, "url": { "raw": "{{URL}}/reviews", @@ -1101,6 +1153,54 @@ }, "response": [] }, + { + "name": "GET Reviews from ES with sortBy", + "event": [ + { + "listen": "test", + "script": { + "id": "290c7b35-fc15-468e-81a8-bd2a4eefcd27", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{ADMIN_TOKEN}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{URL}}/reviews?sortBy=score", + "host": [ + "{{URL}}" + ], + "path": [ + "reviews" + ], + "query": [ + { + "key": "sortBy", + "value": "score" + } + ] + } + }, + "response": [] + }, { "name": "GET Reviews from ES with invalid filters", "event": [ @@ -1284,10 +1384,10 @@ "listen": "test", "script": { "id": "f13eec0d-52e8-4650-b1b0-2db09992067b", - "type": "text/javascript", "exec": [ "" - ] + ], + "type": "text/javascript" } } ], @@ -1305,7 +1405,7 @@ ], "body": { "mode": "raw", - "raw": "{\n\t\"score\": 90.5,\n\t\"scoreCardId\": \"d46a4180-65aa-42ec-a555-5fd21d3d26f8\",\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" + "raw": "{\n\t\"score\": 90.5,\n\t\"scoreCardId\": 123456789,\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" }, "url": { "raw": "{{URL}}/reviews/{{reviewID}}", @@ -1483,13 +1583,13 @@ "listen": "test", "script": { "id": "9a901742-45ac-4e6e-b3c5-3379ed7e74bf", - "type": "text/javascript", "exec": [ "if( responseCode.code === 200) {", " const response = JSON.parse(responseBody);", " pm.environment.set(\"reviewSummationID\", response.id);", "}" - ] + ], + "type": "text/javascript" } } ], @@ -1507,7 +1607,7 @@ ], "body": { "mode": "raw", - "raw": "{\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"aggregateScore\": 97.8,\n\t\"scoreCardId\": \"d46a4180-65aa-42ec-a945-5fd21d3d26f8\",\n\t\"isPassing\": true\n}" + "raw": "{\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"aggregateScore\": 97.8,\n\t\"scoreCardId\": 123456789,\n\t\"isPassing\": true\n}" }, "url": { "raw": "{{URL}}/reviewSummations", @@ -1831,6 +1931,58 @@ }, "response": [] }, + { + "name": "GET Review Summations from ES with sortBy", + "event": [ + { + "listen": "test", + "script": { + "id": "290c7b35-fc15-468e-81a8-bd2a4eefcd27", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{ADMIN_TOKEN}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{URL}}/reviewSummations?sortBy=aggregateScore&orderBy=DESC", + "host": [ + "{{URL}}" + ], + "path": [ + "reviewSummations" + ], + "query": [ + { + "key": "sortBy", + "value": "aggregateScore" + }, + { + "key": "orderBy", + "value": "DESC" + } + ] + } + }, + "response": [] + }, { "name": "GET Review Summations from ES with invalid filters", "event": [ @@ -2014,10 +2166,10 @@ "listen": "test", "script": { "id": "f13eec0d-52e8-4650-b1b0-2db09992067b", - "type": "text/javascript", "exec": [ "" - ] + ], + "type": "text/javascript" } } ], @@ -2035,7 +2187,7 @@ ], "body": { "mode": "raw", - "raw": "{\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"aggregateScore\": 93.5,\n\t\"scoreCardId\": \"d46a4180-65aa-42ec-a945-5fd21d3d26f8\",\n\t\"isPassing\": true\n}" + "raw": "{\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"aggregateScore\": 93.5,\n\t\"scoreCardId\": 123456789,\n\t\"isPassing\": true\n}" }, "url": { "raw": "{{URL}}/reviewSummations/{{reviewSummationID}}", @@ -2491,6 +2643,42 @@ }, "response": [] }, + { + "name": "Get Submissions from ES with sortBy", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{USER_TOKEN}}" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{URL}}/submissions?sortBy=created&orderBy=asc", + "host": [ + "{{URL}}" + ], + "path": [ + "submissions" + ], + "query": [ + { + "key": "sortBy", + "value": "created" + }, + { + "key": "orderBy", + "value": "asc" + } + ] + } + }, + "response": [] + }, { "name": "Get Submissions from ES with invalid filters", "request": { @@ -2761,6 +2949,11 @@ "key": "typeId", "value": "{{artifactID}}", "type": "text" + }, + { + "key": "filename", + "value": "{{filename}}", + "type": "text" } ] }, @@ -2927,6 +3120,38 @@ } }, "response": [] + }, + { + "name": "Get Submissions from ES with filters Copy", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{USER_TOKEN}}" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{URL}}/submissions?type=ContestSubmission", + "host": [ + "{{URL}}" + ], + "path": [ + "submissions" + ], + "query": [ + { + "key": "type", + "value": "ContestSubmission" + } + ] + } + }, + "response": [] } ], "description": "End points related to Submission", diff --git a/docs/submission-api.postman_environment.json b/docs/submission-api.postman_environment.json index dc3761d6..715180a4 100755 --- a/docs/submission-api.postman_environment.json +++ b/docs/submission-api.postman_environment.json @@ -1,5 +1,5 @@ { - "id": "eac995de-0f91-4dd2-a4c7-dab75cc3037e", + "id": "9f46d01c-0036-4350-aa00-c6860b4450de", "name": "submission-api", "values": [ { @@ -36,9 +36,16 @@ "value": "c56a4180-65aa-42ec-a945-5fd21dec0503", "description": "", "enabled": true + }, + { + "key": "filename", + "value": "sampleFileName", + "type": "text", + "description": "", + "enabled": true } ], "_postman_variable_scope": "environment", - "_postman_exported_at": "2019-01-10T10:16:10.847Z", - "_postman_exported_using": "Postman/6.5.3" + "_postman_exported_at": "2019-08-11T08:59:27.296Z", + "_postman_exported_using": "Postman/6.7.4" } \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 4ed97cf3..a4cce83c 100755 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -59,6 +59,8 @@ paths: parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/perPage' + - $ref: '#/parameters/orderBy' + - $ref: '#/parameters/sortBy' # filter parameters - $ref: '#/parameters/filterSubmissionType' - $ref: '#/parameters/filterSubmissionUrl' @@ -67,6 +69,15 @@ paths: - $ref: '#/parameters/filterSubmissionLegacySubmissionId' - $ref: '#/parameters/filterSubmissionLegacyUploadId' - $ref: '#/parameters/filterSubmissionSubmissionPhaseId' + - $ref: '#/parameters/filterSubmissionReviewScore' + - $ref: '#/parameters/filterSubmissionReviewTypeId' + - $ref: '#/parameters/filterSubmissionReviewReviewerId' + - $ref: '#/parameters/filterSubmissionReviewScoreCardId' + - $ref: '#/parameters/filterSubmissionReviewSubmissionId' + - $ref: '#/parameters/filterSubmissionReviewSummationScoreCardId' + - $ref: '#/parameters/filterSubmissionReviewSummationSubmissionId' + - $ref: '#/parameters/filterSubmissionReviewSummationAggregateScore' + - $ref: '#/parameters/filterSubmissionReviewSummationIsPassing' responses: 200: description: OK - the request was successful, the submissions resource are returned. @@ -80,6 +91,9 @@ paths: url: 'https://software.topcoder.com/review/actions/DownloadContestSubmission?uid=123456' memberId: 'a12a4180-65aa-42ec-a945-5fd21dec0501' challengeId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' + legacySubmissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' + legacyUploadId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' + submissionPhaseId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' created: '2018-05-20T07:00:30.123Z' updated: '2018-06-01T07:36:28.178Z' createdBy: 'topcoder user' @@ -89,6 +103,9 @@ paths: url: 'https://software.topcoder.com/review/actions/DownloadContestSubmission?uid=123457' memberId: 'a12a4180-65aa-42ec-a945-5fd21dec0552' challengeId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' + legacySubmissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' + legacyUploadId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' + submissionPhaseId: 'a12a4180-65aa-42ec-a945-5fd21dec0502' created: '2018-05-20T08:00:30.000Z' updated: '2018-06-01T09:23:00.178Z' createdBy: 'topcoder user' @@ -458,6 +475,11 @@ paths: required: true type: string example: 'c56a4180-65aa-42ec-a945-5fd21dec0503' + - in: formData + name: filename + required: true + type: string + example: 'genericFilename' responses: 200: description: Artifact created successfully @@ -578,11 +600,14 @@ paths: parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/perPage' + - $ref: '#/parameters/orderBy' + - $ref: '#/parameters/sortBy' # filter parameters - $ref: '#/parameters/filterReviewSummationSubmissionId' - $ref: '#/parameters/filterReviewSummationAaggregateScore' - $ref: '#/parameters/filterReviewSummationScoreCardId' - $ref: '#/parameters/filterReviewSummationIsPassing' + - $ref: '#/parameters/filterReviewSummationIsFinal' responses: 200: description: OK - the request was successful, the resource are returned. @@ -595,8 +620,9 @@ paths: - id: 'a12a4180-65aa-42ec-a945-5fd21dec1503' submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec1567' aggregateScore: 17.8 - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587' + scoreCardId: 123456789 isPassing: false + isFinal: false created: '2018-05-20T07:00:30.123Z' updated: '2018-06-01T07:36:28.178Z' createdBy: copilot @@ -604,8 +630,9 @@ paths: - id: 'a12a4180-65aa-42ec-a945-5fd21dec1504' submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec1568' aggregateScore: 97.8 - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587' + scoreCardId: 123456789 isPassing: true + isFinal: true created: '2018-05-20T07:00:30.123Z' updated: '2018-06-01T07:36:28.178Z' createdBy: copilot @@ -661,6 +688,7 @@ paths: - $ref: '#/parameters/filterReviewSummationAaggregateScore' - $ref: '#/parameters/filterReviewSummationScoreCardId' - $ref: '#/parameters/filterReviewSummationIsPassing' + - $ref: '#/parameters/filterReviewSummationIsFinal' responses: 200: description: OK - The request was successful. @@ -889,6 +917,8 @@ paths: parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/perPage' + - $ref: '#/parameters/orderBy' + - $ref: '#/parameters/sortBy' # filter parameters - $ref: '#/parameters/filterReviewScore' - $ref: '#/parameters/filterReviewTypeId' @@ -908,7 +938,7 @@ paths: score: 95.5 typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503' reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503' - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503' + scoreCardId: 123456789 submissionId: 'd67a4180-65aa-42ec-a945-5fd21dec0503' created: '2018-05-20T07:00:30.123Z' updated: '2018-06-01T07:36:28.178Z' @@ -918,7 +948,7 @@ paths: score: 73.2 typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503' reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503' - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503' + scoreCardId: 123456789 submissionId: 'd23a4180-65aa-42ec-a945-5fd21dec0503' created: '2018-05-20T07:00:30.123Z' updated: '2018-06-01T07:36:28.178Z' @@ -1025,8 +1055,8 @@ paths: schema: $ref: '#/definitions/Review' responses: - 201: - description: Created - The request was successful and the resource is returned. + 200: + description: The request was successful and the resource is returned. schema: $ref: '#/definitions/Review' @@ -1203,6 +1233,8 @@ paths: parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/perPage' + - $ref: '#/parameters/orderBy' + - $ref: '#/parameters/sortBy' # filter parameters - $ref: '#/parameters/filterReviewTypeName' - $ref: '#/parameters/filterReviewTypeIsActive' @@ -1319,7 +1351,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/ReviewType' + $ref: '#/definitions/UpdatableReviewType' responses: 201: description: Created - The request was successful and the resource is returned. @@ -1502,6 +1534,21 @@ parameters: default: 20 maximum: 100 + orderBy: + name: orderBy + in: query + description: The sorting order (asc/desc). + required: false + type: string + enum: [asc,desc,ASC,DESC] + + sortBy: + name: sortBy + in: query + description: The field to sort the result by. + required: false + type: string + filterSubmissionType: in: query name: type @@ -1561,6 +1608,69 @@ parameters: - type: string - type: integer + filterSubmissionReviewScore: + in: query + name: review.score + description: The score filter of the reviews associated with the submission. + required: false + type: integer + + filterSubmissionReviewTypeId: + in: query + name: review.typeId + description: The typeId filter of the reviews associated with the submission. + required: false + type: string + + filterSubmissionReviewReviewerId: + in: query + name: review.reviewerId + description: The reviewerId filter of the reviews associated with the submission. + required: false + type: string + + filterSubmissionReviewScoreCardId: + in: query + name: review.scoreCardId + description: The scoreCardId filter of the reviews associated with the submission. + required: false + type: integer + + filterSubmissionReviewSubmissionId: + in: query + name: review.submissionId + description: The submissionId filter of the reviews associated with the submission. + required: false + type: string + + filterSubmissionReviewSummationScoreCardId: + in: query + name: reviewSummation.scoreCardId + description: The scoreCardId filter of the review summaions associated with the submission. + required: false + type: integer + + filterSubmissionReviewSummationSubmissionId: + in: query + name: reviewSummation.submissionId + description: The submissionId filter of the review summaions associated with the submission. + required: false + type: string + + filterSubmissionReviewSummationAggregateScore: + in: query + name: reviewSummation.aggregateScore + description: The aggregateScore filter of the review summaions associated with the submission. + required: false + type: integer + + filterSubmissionReviewSummationIsPassing: + in: query + name: reviewSummation.isPassing + description: The isPassing filter of the review summaions associated with the submission. + required: false + type: string + filterReviewSummationSubmissionId: in: query name: submissionId @@ -1581,7 +1691,7 @@ parameters: name: scoreCardId description: The score card id filter for review summations. required: false - type: string + type: integer filterReviewSummationIsPassing: in: query @@ -1590,6 +1700,13 @@ parameters: required: false type: boolean + filterReviewSummationIsFinal: + in: query + name: isFinal + description: The final boolean flag filter for review summations. + required: false + type: boolean + filterReviewScore: in: query name: score @@ -1617,7 +1734,7 @@ parameters: name: scoreCardId description: The score card id filter for reviews. required: false - type: string + type: integer filterReviewSubmissionId: in: query @@ -1740,12 +1857,29 @@ definitions: - type: integer description: The submission challenge id. example: 'a12bc180-65aa-42ec-a945-5fd21dec1567' + legacySubmissionId: + oneOf: + - type: string + - type: integer + description: The legacy submission id. + example: '70b0e2e7-f824-4248-8398-54ee10ff0db9' + legacyUploadId: + oneOf: + - type: string + - type: integer + description: The legacy upload id. + example: '5da27562-eaec-4c9f-ad1c-ddfbed6ffdbc' + submissionPhaseId: + oneOf: + - type: string + - type: integer + description: The submission phase id. + example: '5dea6d9e-161a-4c7a-b316-597c73a7b8f4' UpdatableSubmission: description: The submission entity fields that updates whole entity. type: object required: - - type - url - memberId - challengeId @@ -1786,13 +1920,17 @@ definitions: description: The review summation aggregate score. example: 97.8 scoreCardId: - type: string + type: integer description: The review summation score card id. - example: 'a12bc180-65aa-42aa-a945-5fd21dec1567' + example: 123456789 isPassing: type: boolean description: The review summation passing boolean flag. example: true + isFinal: + type: boolean + description: The review summation final boolean flag. + example: true metadata: type: object description: Review summation metadata in JSON format @@ -1847,9 +1985,9 @@ definitions: example: 'a12bc280-65ab-42ec-a945-5fd21dec1567' description: The review reviewer id. scoreCardId: - type: string + type: integer description: The review score card id. - example: 'a12bd180-65ab-42ec-a945-5fd21dec1567' + example: 123456789 submissionId: type: string description: The submission id. diff --git a/package-lock.json b/package-lock.json index 96d0e357..033a2606 100755 --- a/package-lock.json +++ b/package-lock.json @@ -2276,6 +2276,12 @@ "acorn-jsx": "^3.0.0" } }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", @@ -3609,10 +3615,12 @@ }, "js-yaml": { "version": "3.11.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "dev": true, "requires": { - "argparse": "^1.0.7" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "jsbn": { diff --git a/scripts/data/ReviewSummations.json b/scripts/data/ReviewSummations.json index c3ff68a9..81edb9e4 100644 --- a/scripts/data/ReviewSummations.json +++ b/scripts/data/ReviewSummations.json @@ -3,7 +3,7 @@ "id": "e45e4180-65aa-42ec-a945-5fd21dec1504", "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0501", "aggregateScore": 99.0, - "scoreCardId": "a12a4180-65aa-42ec-a945-5fd21dec0587", + "scoreCardId": 123456789, "isPassing": true, "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", diff --git a/scripts/data/Reviews.json b/scripts/data/Reviews.json index 62d70252..40b4e5de 100644 --- a/scripts/data/Reviews.json +++ b/scripts/data/Reviews.json @@ -4,7 +4,7 @@ "score": 95.5, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0501", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -16,7 +16,7 @@ "score": 92.0, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0501", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0501", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -28,7 +28,7 @@ "score": 80.83, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0503", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -40,7 +40,7 @@ "score": 85.62, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0502", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0503", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -52,7 +52,7 @@ "score": 100, "typeId": "f28b2725-ef90-4495-af59-ceb2bd98fc10", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0503", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -64,7 +64,7 @@ "score": 65.0, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0504", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -76,7 +76,7 @@ "score": 68.0, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0502", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0504", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -88,7 +88,7 @@ "score": 100, "typeId": "f28b2725-ef90-4495-af59-ceb2bd98fc10", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0505", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -100,7 +100,7 @@ "score": 92.5, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0505", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", diff --git a/scripts/data/Submissions.json b/scripts/data/Submissions.json index e38bd8b8..0d9a3b4e 100644 --- a/scripts/data/Submissions.json +++ b/scripts/data/Submissions.json @@ -11,7 +11,7 @@ "score": 95.5, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0501", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -23,7 +23,7 @@ "score": 92.0, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0501", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0501", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -36,7 +36,7 @@ "id": "e45e4180-65aa-42ec-a945-5fd21dec1504", "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0501", "aggregateScore": 99.0, - "scoreCardId": "a12a4180-65aa-42ec-a945-5fd21dec0587", + "scoreCardId": 123456789, "isPassing": true, "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -72,7 +72,7 @@ "score": 80.83, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0503", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -84,7 +84,7 @@ "score": 85.62, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0502", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0503", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -96,7 +96,7 @@ "score": 100, "typeId": "f28b2725-ef90-4495-af59-ceb2bd98fc10", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0503", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -121,7 +121,7 @@ "score": 65.0, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0504", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -133,7 +133,7 @@ "score": 68.0, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0502", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0504", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -158,7 +158,7 @@ "score": 100, "typeId": "f28b2725-ef90-4495-af59-ceb2bd98fc10", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0505", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", @@ -183,7 +183,7 @@ "score": 92.5, "typeId": "c56a4180-65aa-42ec-a945-5fd21dec0503", "reviewerId": "c23a4180-65aa-42ec-a945-5fd21dec0503", - "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", + "scoreCardId": 123456789, "submissionId": "a12a4180-65aa-42ec-a945-5fd21dec0505", "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", diff --git a/src/bootstrap.js b/src/bootstrap.js index f49bb55d..5a3d1fa6 100755 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -12,7 +12,7 @@ const logger = require('./common/logger') joi.id = () => joi.number().integer().min(1) joi.score = () => joi.number() joi.pageSize = () => joi.number().integer().min(1).max(config.get('MAX_PAGE_SIZE')) -joi.sortOrder = () => joi.string().valid('asc', 'desc', 'ASC', 'DESC').default('asc') +joi.sortOrder = () => joi.string().valid('asc', 'desc', 'ASC', 'DESC') function buildServices (dir) { const files = fs.readdirSync(dir) diff --git a/src/common/helper.js b/src/common/helper.js index fc75cbd5..aee13f18 100755 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -125,8 +125,10 @@ function camelize (str) { function prepESFilter (query, actResource) { const pageSize = query.perPage || config.get('PAGE_SIZE') const page = query.page || 1 - const filters = _.omit(query, ['perPage', 'page']) - // Add match phrase filters for all query filters except page and perPage + const { sortBy, orderBy } = query + const filters = _.omit(query, ['perPage', 'page', 'sortBy', 'orderBy']) + // Add match phrase filters for all query filters + // except page, perPage, sortBy & orderBy const boolQuery = [] const reviewFilters = [] const reviewSummationFilters = [] @@ -190,11 +192,23 @@ function prepESFilter (query, actResource) { } } - // Add sorting for submission - if (actResource === 'submission') { - searchCriteria.body.sort = [ - { 'created': { 'order': 'asc' } } - ] + const esQuerySortArray = [] + + if (sortBy) { + const obj = {} + obj[sortBy] = { 'order': orderBy || 'asc' } + esQuerySortArray.push(obj) + } + + // Internal sorting by 'updated' timestamp + if (actResource !== 'reviewType') { + esQuerySortArray.push({ + updated: { 'order': 'desc' } + }) + } + + if (esQuerySortArray.length > 0) { + searchCriteria.body.sort = esQuerySortArray } return searchCriteria diff --git a/src/services/ArtifactService.js b/src/services/ArtifactService.js index 3e9e5c24..f9f31482 100644 --- a/src/services/ArtifactService.js +++ b/src/services/ArtifactService.js @@ -89,7 +89,7 @@ function * createArtifact (files, submissionId, entity) { logger.info('Creating a new Artifact') if (files && files.artifact) { const uFileType = fileTypeFinder(files.artifact.data).ext // File type of uploaded file - fileName = `${submissionId}/${entity.typeId}.${uFileType}` + fileName = `${submissionId}/${entity.filename}.${uFileType}` let exist // Check the existence of file in S3 bucket try { @@ -100,7 +100,7 @@ function * createArtifact (files, submissionId, entity) { } if (exist) { - throw new errors.HttpStatusError(409, `Artifact ${entity.typeId}.${uFileType} already exists for Submission ${submissionId}`) + throw new errors.HttpStatusError(409, `Artifact ${entity.filename}.${uFileType} already exists for Submission ${submissionId}`) } // Upload the artifact to S3 yield _uploadToS3(files.artifact, fileName) @@ -114,7 +114,8 @@ createArtifact.schema = { files: joi.any().required(), submissionId: joi.string().guid().required(), entity: joi.object().keys({ - typeId: joi.string().uuid().required() + typeId: joi.string().uuid().required(), + filename: joi.string().required() }).required() } diff --git a/src/services/ReviewService.js b/src/services/ReviewService.js index 41d535da..49e8db3f 100644 --- a/src/services/ReviewService.js +++ b/src/services/ReviewService.js @@ -82,16 +82,24 @@ function * listReviews (query) { return yield helper.fetchFromES(query, helper.camelize(table)) } +const listReviewsQuerySchema = { + score: joi.score(), + typeId: joi.string().uuid(), + reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()), + scoreCardId: joi.id(), + submissionId: joi.string().uuid(), + page: joi.id(), + perPage: joi.pageSize(), + orderBy: joi.sortOrder() +} + +listReviewsQuerySchema.sortBy = joi.string().valid(_.difference( + Object.keys(listReviewsQuerySchema), + ['page', 'perPage', 'orderBy'] +)) + listReviews.schema = { - query: joi.object().keys({ - score: joi.score(), - typeId: joi.string().uuid(), - reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()), - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()), - submissionId: joi.string().uuid(), - page: joi.id(), - perPage: joi.pageSize() - }) + query: joi.object().keys(listReviewsQuerySchema).with('orderBy', 'sortBy') } /** @@ -146,8 +154,10 @@ createReview.schema = { entity: joi.object().keys({ score: joi.score().required(), typeId: joi.string().uuid().required(), - reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), + reviewerId: joi.alternatives() + .try(joi.id(), joi.string().uuid()).required() + .error(errors => ({message: '"reviewerId" must be a number or a string'})), + scoreCardId: joi.id().required(), submissionId: joi.string().uuid().required(), metadata: joi.object() }).required() @@ -244,7 +254,7 @@ updateReview.schema = { score: joi.score().required(), typeId: joi.string().uuid().required(), reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), + scoreCardId: joi.id().required(), submissionId: joi.string().uuid().required(), metadata: joi.object() }).required() @@ -268,7 +278,7 @@ patchReview.schema = { score: joi.score(), typeId: joi.string().uuid(), reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()), - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()), + scoreCardId: joi.id(), submissionId: joi.string().uuid(), metadata: joi.object() }) diff --git a/src/services/ReviewSummationService.js b/src/services/ReviewSummationService.js index b6a6d028..741cc38b 100644 --- a/src/services/ReviewSummationService.js +++ b/src/services/ReviewSummationService.js @@ -58,16 +58,24 @@ function * listReviewSummations (query) { return yield helper.fetchFromES(query, helper.camelize(table)) } +const listReviewSummationsQuerySchema = { + scoreCardId: joi.id(), + submissionId: joi.string().uuid(), + aggregateScore: joi.score(), + isPassing: joi.boolean(), + isFinal: joi.boolean(), + page: joi.id(), + perPage: joi.pageSize(), + orderBy: joi.sortOrder() +} + +listReviewSummationsQuerySchema.sortBy = joi.string().valid(_.difference( + Object.keys(listReviewSummationsQuerySchema), + ['page', 'perPage', 'orderBy'] +)) + listReviewSummations.schema = { - query: joi.object().keys({ - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()), - submissionId: joi.string().uuid(), - aggregateScore: joi.score(), - isPassing: joi.boolean(), - isFinal: joi.boolean(), - page: joi.id(), - perPage: joi.pageSize() - }) + query: joi.object().keys(listReviewSummationsQuerySchema).with('orderBy', 'sortBy') } /** @@ -121,7 +129,7 @@ function * createReviewSummation (authUser, entity) { createReviewSummation.schema = { authUser: joi.object().required(), entity: joi.object().keys({ - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), + scoreCardId: joi.id().required(), submissionId: joi.string().uuid().required(), aggregateScore: joi.score().required(), isPassing: joi.boolean().required(), @@ -233,7 +241,7 @@ updateReviewSummation.schema = { authUser: joi.object().required(), reviewSummationId: joi.string().uuid().required(), entity: joi.object().keys({ - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), + scoreCardId: joi.id().required(), submissionId: joi.string().uuid().required(), aggregateScore: joi.score().required(), isPassing: joi.boolean().required(), @@ -257,7 +265,7 @@ patchReviewSummation.schema = { authUser: joi.object().required(), reviewSummationId: joi.string().uuid().required(), entity: joi.object().keys({ - scoreCardId: joi.alternatives().try(joi.id(), joi.string().uuid()), + scoreCardId: joi.id(), submissionId: joi.string().uuid(), aggregateScore: joi.score(), isPassing: joi.boolean(), diff --git a/src/services/ReviewTypeService.js b/src/services/ReviewTypeService.js index 63d67b0c..f5aff164 100755 --- a/src/services/ReviewTypeService.js +++ b/src/services/ReviewTypeService.js @@ -57,13 +57,21 @@ function * listReviewTypes (query) { return yield helper.fetchFromES(query, helper.camelize(table)) } +const listReviewTypesQuerySchema = { + name: joi.string(), + isActive: joi.boolean(), + page: joi.id(), + perPage: joi.pageSize(), + orderBy: joi.sortOrder() +} + +listReviewTypesQuerySchema.sortBy = joi.string().valid(_.difference( + Object.keys(listReviewTypesQuerySchema), + ['page', 'perPage', 'orderBy'] +)) + listReviewTypes.schema = { - query: joi.object().keys({ - name: joi.string(), - isActive: joi.boolean(), - page: joi.id(), - perPage: joi.pageSize() - }) + query: joi.object().keys(listReviewTypesQuerySchema).with('orderBy', 'sortBy') } /** diff --git a/src/services/SubmissionService.js b/src/services/SubmissionService.js index 077e6337..c146ecb7 100755 --- a/src/services/SubmissionService.js +++ b/src/services/SubmissionService.js @@ -181,27 +181,35 @@ function * listSubmissions (query) { return yield helper.fetchFromES(query, helper.camelize(table)) } +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()), + legacySubmissionId: joi.alternatives().try(joi.id(), joi.string().uuid()), + legacyUploadId: joi.alternatives().try(joi.id(), joi.string().uuid()), + submissionPhaseId: joi.alternatives().try(joi.id(), joi.string().uuid()), + page: joi.id(), + perPage: joi.pageSize(), + orderBy: joi.sortOrder(), + 'review.score': joi.score(), + 'review.typeId': joi.string().uuid(), + 'review.reviewerId': joi.string().uuid(), + 'review.scoreCardId': joi.id(), + 'review.submissionId': joi.string().uuid(), + 'reviewSummation.scoreCardId': joi.id(), + 'reviewSummation.submissionId': joi.string().uuid(), + 'reviewSummation.aggregateScore': joi.score(), + 'reviewSummation.isPassing': joi.boolean() +} + +listSubmissionsQuerySchema.sortBy = joi.string().valid(_.difference( + Object.keys(listSubmissionsQuerySchema), + ['page', 'perPage', 'orderBy'] +)) + listSubmissions.schema = { - query: joi.object().keys({ - 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()), - legacySubmissionId: joi.alternatives().try(joi.id(), joi.string().uuid()), - legacyUploadId: joi.alternatives().try(joi.id(), joi.string().uuid()), - submissionPhaseId: joi.alternatives().try(joi.id(), joi.string().uuid()), - page: joi.id(), - perPage: joi.pageSize(), - 'review.score': joi.score(), - 'review.typeId': joi.string().uuid(), - 'review.reviewerId': joi.string().uuid(), - 'review.scoreCardId': joi.string().uuid(), - 'review.submissionId': joi.string().uuid(), - 'reviewSummation.scoreCardId': joi.string().uuid(), - 'reviewSummation.submissionId': joi.string().uuid(), - 'reviewSummation.aggregateScore': joi.score(), - 'reviewSummation.isPassing': joi.boolean() - }) + query: joi.object().keys(listSubmissionsQuerySchema).with('orderBy', 'sortBy') } /** diff --git a/test/common/testData.js b/test/common/testData.js index 83937171..e932a3a2 100644 --- a/test/common/testData.js +++ b/test/common/testData.js @@ -251,7 +251,7 @@ const testReview = { score: 92, reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503', + scoreCardId: 123456789, typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0501', created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -266,7 +266,7 @@ const testReviewPatch = { score: 90, reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503', + scoreCardId: 123456789, typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0501', created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -288,7 +288,7 @@ const testReviewES = { score: 92, reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503', + scoreCardId: 123456789, typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0501', created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -313,7 +313,7 @@ const testReviewsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', updatedBy: 'admin', createdBy: 'admin', - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503', id: 'd24d4180-65aa-42ec-a945-5fd21dec0501', @@ -328,7 +328,7 @@ const testReviewsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0504', updatedBy: 'admin', createdBy: 'admin', - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503', id: 'd24d4180-65aa-42ec-a945-5fd21dec0504', @@ -343,7 +343,7 @@ const testReviewsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0502', updatedBy: 'admin', createdBy: 'admin', - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503', id: 'd24d4180-65aa-42ec-a945-5fd21dec0502', @@ -358,7 +358,7 @@ const testReviewsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0503', updatedBy: 'admin', createdBy: 'admin', - scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503', id: 'd24d4180-65aa-42ec-a945-5fd21dec0503', @@ -374,7 +374,7 @@ const testReviewSummation = { aggregateScore: 99, isPassing: true, submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', createdBy: 'copilot', @@ -388,7 +388,7 @@ const testReviewSummationPatch = { aggregateScore: 78.5, isPassing: false, submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', createdBy: 'copilot', @@ -409,7 +409,7 @@ const testReviewSummationES = { aggregateScore: 99, isPassing: true, submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', createdBy: 'copilot', @@ -432,7 +432,7 @@ const testReviewSummationsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0503', updatedBy: 'copilot', createdBy: 'copilot', - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', id: 'e45e4180-65aa-42ec-a945-5fd21dec1503', isPassing: false, @@ -446,7 +446,7 @@ const testReviewSummationsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', updatedBy: 'copilot', createdBy: 'copilot', - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', id: 'e45e4180-65aa-42ec-a945-5fd21dec1501', isPassing: false, @@ -460,7 +460,7 @@ const testReviewSummationsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0502', updatedBy: 'copilot', createdBy: 'copilot', - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', id: 'e45e4180-65aa-42ec-a945-5fd21dec1502', isPassing: true, @@ -474,7 +474,7 @@ const testReviewSummationsES = { submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0504', updatedBy: 'copilot', createdBy: 'copilot', - scoreCardId: 'a12a4180-65aa-42ec-a945-5fd21dec0587', + scoreCardId: 123456789, created: '2018-05-20T07:00:30.123Z', id: 'e45e4180-65aa-42ec-a945-5fd21dec1504', isPassing: true, diff --git a/test/e2e/ReviewService.test.js b/test/e2e/ReviewService.test.js index 6cc17d26..b51b60f0 100644 --- a/test/e2e/ReviewService.test.js +++ b/test/e2e/ReviewService.test.js @@ -462,6 +462,17 @@ describe('Review Service tests', () => { }) }) + it('Getting reviews with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/reviews?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ diff --git a/test/e2e/ReviewSummationService.test.js b/test/e2e/ReviewSummationService.test.js index 2784521b..5f003f78 100644 --- a/test/e2e/ReviewSummationService.test.js +++ b/test/e2e/ReviewSummationService.test.js @@ -425,6 +425,17 @@ describe('Review Summation Service tests', () => { }) }) + it('Getting reviewSummations with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/reviewSummations?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ diff --git a/test/e2e/ReviewTypeService.test.js b/test/e2e/ReviewTypeService.test.js index adc59c65..cae90b64 100644 --- a/test/e2e/ReviewTypeService.test.js +++ b/test/e2e/ReviewTypeService.test.js @@ -417,6 +417,17 @@ describe('ReviewType Service tests', () => { }) }) + it('Getting review types with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/reviewTypes?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ diff --git a/test/e2e/SubmissionService.test.js b/test/e2e/SubmissionService.test.js index ba916050..878b138c 100644 --- a/test/e2e/SubmissionService.test.js +++ b/test/e2e/SubmissionService.test.js @@ -515,6 +515,17 @@ describe('Submission Service tests', () => { }) }) + it('Getting submissions with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/submissions?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ diff --git a/test/unit/ReviewService.test.js b/test/unit/ReviewService.test.js index 33f75fdc..70cef4c6 100644 --- a/test/unit/ReviewService.test.js +++ b/test/unit/ReviewService.test.js @@ -443,6 +443,17 @@ describe('Review Service tests', () => { }) }) + it('Getting reviews with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/reviews?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ diff --git a/test/unit/ReviewSummationService.test.js b/test/unit/ReviewSummationService.test.js index a9ca2bcb..a3b7ed90 100644 --- a/test/unit/ReviewSummationService.test.js +++ b/test/unit/ReviewSummationService.test.js @@ -409,6 +409,17 @@ describe('Review Summation Service tests', () => { }) }) + it('Getting reviewSummations with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/reviewSummations?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ diff --git a/test/unit/ReviewTypeService.test.js b/test/unit/ReviewTypeService.test.js index 9c1105de..2fe5e702 100644 --- a/test/unit/ReviewTypeService.test.js +++ b/test/unit/ReviewTypeService.test.js @@ -404,6 +404,17 @@ describe('ReviewType Service tests', () => { }) }) + it('Getting review types with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/reviewTypes?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ diff --git a/test/unit/SubmissionService.test.js b/test/unit/SubmissionService.test.js index c9b7a942..b6c93b30 100644 --- a/test/unit/SubmissionService.test.js +++ b/test/unit/SubmissionService.test.js @@ -516,6 +516,17 @@ describe('Submission Service tests', () => { }) }) + it('Getting submissions with orderBy without sortBy filter should throw 400', (done) => { + chai.request(app) + .get(`${config.API_VERSION}/submissions?orderBy=asc`) + .set('Authorization', `Bearer ${config.ADMIN_TOKEN}`) + .end((err, res) => { + res.should.have.status(400) + res.body.message.should.be.eql('"orderBy" missing required peer "sortBy"') + done() + }) + }) + /* * TODO: Auth library ideally need to throw 401 for this scenario */ From 170867dffc42b00598cbc47348017f3a98105b5a Mon Sep 17 00:00:00 2001 From: Mithun Kamath Date: Sun, 18 Aug 2019 17:29:10 +0530 Subject: [PATCH 2/2] 1. Remove typeId and filename for artifacts - use file's name itself as the artifact name 2. Prevent sort by name for review type (text field cannot be sorted in ES) --- docs/swagger.yaml | 14 ++------------ src/services/ArtifactService.js | 9 +++------ src/services/ReviewTypeService.js | 2 +- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/docs/swagger.yaml b/docs/swagger.yaml index a4cce83c..74923d39 100755 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -469,17 +469,7 @@ paths: name: artifact type: file required: true - description: Artifact to be uploaded - - in: formData - name: typeId - required: true - type: string - example: 'c56a4180-65aa-42ec-a945-5fd21dec0503' - - in: formData - name: filename - required: true - type: string - example: 'genericFilename' + description: Artifact to be uploaded. Pass the name of the artifact along with the data responses: 200: description: Artifact created successfully @@ -1781,7 +1771,7 @@ parameters: fileParam: name: file in: path - description: artifact id + description: artifact id (its filename) required: true type: string diff --git a/src/services/ArtifactService.js b/src/services/ArtifactService.js index f9f31482..9243eaeb 100644 --- a/src/services/ArtifactService.js +++ b/src/services/ArtifactService.js @@ -89,7 +89,7 @@ function * createArtifact (files, submissionId, entity) { logger.info('Creating a new Artifact') if (files && files.artifact) { const uFileType = fileTypeFinder(files.artifact.data).ext // File type of uploaded file - fileName = `${submissionId}/${entity.filename}.${uFileType}` + fileName = `${submissionId}/${files.artifact.name}.${uFileType}` let exist // Check the existence of file in S3 bucket try { @@ -100,7 +100,7 @@ function * createArtifact (files, submissionId, entity) { } if (exist) { - throw new errors.HttpStatusError(409, `Artifact ${entity.filename}.${uFileType} already exists for Submission ${submissionId}`) + throw new errors.HttpStatusError(409, `Artifact ${files.artifact.name}.${uFileType} already exists for Submission ${submissionId}`) } // Upload the artifact to S3 yield _uploadToS3(files.artifact, fileName) @@ -113,10 +113,7 @@ function * createArtifact (files, submissionId, entity) { createArtifact.schema = { files: joi.any().required(), submissionId: joi.string().guid().required(), - entity: joi.object().keys({ - typeId: joi.string().uuid().required(), - filename: joi.string().required() - }).required() + entity: joi.object() } /** diff --git a/src/services/ReviewTypeService.js b/src/services/ReviewTypeService.js index f5aff164..ac2801e2 100755 --- a/src/services/ReviewTypeService.js +++ b/src/services/ReviewTypeService.js @@ -67,7 +67,7 @@ const listReviewTypesQuerySchema = { listReviewTypesQuerySchema.sortBy = joi.string().valid(_.difference( Object.keys(listReviewTypesQuerySchema), - ['page', 'perPage', 'orderBy'] + ['page', 'perPage', 'orderBy', 'name'] )) listReviewTypes.schema = {