diff --git a/README.md b/README.md index e86242b2..8a4496cd 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,9 @@ AUTH0_AUDIENCE_UBAHN= AUTH0_CLIENT_ID= AUTH0_CLIENT_SECRET= - + # necessary if you'll utilize email functionality of interviews + INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID= + INTERVIEW_INVITATION_SENDER_EMAIL= # Locally deployed services (via docker-compose) ES_HOST=dockerhost:9200 DATABASE_URL=postgres://postgres:postgres@dockerhost:5432/postgres diff --git a/app-constants.js b/app-constants.js index 7ee4c5f5..71f9dce1 100644 --- a/app-constants.js +++ b/app-constants.js @@ -44,7 +44,28 @@ const Scopes = { READ_WORK_PERIOD_PAYMENT: 'read:taas-workPeriodPayments', CREATE_WORK_PERIOD_PAYMENT: 'create:taas-workPeriodPayments', UPDATE_WORK_PERIOD_PAYMENT: 'update:taas-workPeriodPayments', - ALL_WORK_PERIOD_PAYMENT: 'all:taas-workPeriodPayments' + ALL_WORK_PERIOD_PAYMENT: 'all:taas-workPeriodPayments', + // interview + READ_INTERVIEW: 'read:taas-interviews', + CREATE_INTERVIEW: 'create:taas-interviews', + UPDATE_INTERVIEW: 'update:taas-interviews', + ALL_INTERVIEW: 'all:taas-interviews' +} + +// Interview related constants +const Interviews = { + Status: { + Scheduling: 'Scheduling', + Scheduled: 'Scheduled', + RequestedForReschedule: 'Requested for reschedule', + Rescheduled: 'Rescheduled', + Completed: 'Completed', + Cancelled: 'Cancelled' + }, + XaiTemplate: { + '30MinInterview': '30-min-interview', + '60MinInterview': '60-min-interview' + } } const ChallengeStatus = { @@ -62,6 +83,7 @@ module.exports = { UserRoles, FullManagePermissionRoles, Scopes, + Interviews, ChallengeStatus, PaymentProcessingSwitch } diff --git a/app.js b/app.js index fc52ee99..7f3d7d85 100644 --- a/app.js +++ b/app.js @@ -9,8 +9,10 @@ const express = require('express') const cors = require('cors') const HttpStatus = require('http-status-codes') const interceptor = require('express-interceptor') +const schedule = require('node-schedule') const logger = require('./src/common/logger') const eventHandlers = require('./src/eventHandlers') +const interviewService = require('./src/services/InterviewService') // setup express app const app = express() @@ -93,6 +95,8 @@ app.use((err, req, res, next) => { const server = app.listen(app.get('port'), () => { logger.info({ component: 'app', message: `Express server listening on port ${app.get('port')}` }) eventHandlers.init() + // schedule updateCompletedInterviews to run every hour + schedule.scheduleJob('0 0 * * * *', interviewService.updateCompletedInterviews) }) if (process.env.NODE_ENV === 'test') { diff --git a/config/default.js b/config/default.js index 32f53d41..c67a54c3 100644 --- a/config/default.js +++ b/config/default.js @@ -126,6 +126,13 @@ module.exports = { TAAS_WORK_PERIOD_PAYMENT_UPDATE_TOPIC: process.env.TAAS_WORK_PERIOD_PAYMENT_UPDATE_TOPIC || 'taas.workperiodpayment.update', // the delete work period payment entity Kafka message topic TAAS_WORK_PERIOD_PAYMENT_DELETE_TOPIC: process.env.TAAS_WORK_PERIOD_PAYMENT_DELETE_TOPIC || 'taas.workperiodpayment.delete', + // topics for interview service + // the request interview Kafka message topic + TAAS_INTERVIEW_REQUEST_TOPIC: process.env.TAAS_INTERVIEW_REQUEST_TOPIC || 'taas.interview.requested', + // the interview update Kafka message topic + TAAS_INTERVIEW_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_UPDATE_TOPIC || 'taas.interview.update', + // the interview bulk update Kafka message topic + TAAS_INTERVIEW_BULK_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_BULK_UPDATE_TOPIC || 'taas.interview.bulkUpdate', // the Kafka message topic for sending email EMAIL_TOPIC: process.env.EMAIL_TOPIC || 'external.action.email', @@ -135,10 +142,18 @@ module.exports = { // the emails address for receiving the issue report // REPORT_ISSUE_EMAILS may contain comma-separated list of email which is converted to array REQUEST_EXTENSION_EMAILS: (process.env.REQUEST_EXTENSION_EMAILS || '').split(','), + // the emails address for interview invitation + // INTERVIEW_INVITATION_CC_LIST may contain comma-separated list of email which is converted to array + // scheduler@x.ai should be in the CC list + INTERVIEW_INVITATION_CC_LIST: (process.env.INTERVIEW_INVITATION_CC_LIST || 'scheduler@x.ai').split(','), // SendGrid email template ID for reporting issue REPORT_ISSUE_SENDGRID_TEMPLATE_ID: process.env.REPORT_ISSUE_SENDGRID_TEMPLATE_ID, // SendGrid email template ID for requesting extension REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID: process.env.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID, + // SendGrid email template ID for interview invitation + INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID: process.env.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID, + // The sender (aka `from`) email for invitation. + INTERVIEW_INVITATION_SENDER_EMAIL: process.env.INTERVIEW_INVITATION_SENDER_EMAIL, // the URL where TaaS App is hosted TAAS_APP_URL: process.env.TAAS_APP_URL || 'https://platform.topcoder-dev.com/taas/myteams', // environment variables for Payment Service diff --git a/config/email_template.config.js b/config/email_template.config.js index bc2d803a..7de8ad80 100644 --- a/config/email_template.config.js +++ b/config/email_template.config.js @@ -59,5 +59,29 @@ module.exports = { '{{text}}', recipients: config.REPORT_ISSUE_EMAILS, sendgridTemplateId: config.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID + }, + + /* Request interview for a job candidate + * + * - interviewType: the x.ai interview type. Example: "30-min-interview" + * - candidateName: Full name of candidate. Example: "John Doe" + * - jobName: The title of the job. Example: "TaaS API Misc Updates" + * - customMessage: if it's needed, a custom message can be added to the end of email. Example: "I would like to invite you for an interview..." + * + * Template (defined in SendGrid): + * Subject: '/{{interviewType}} tech interview with {{candidateName}} for {{jobName}} is requested by the Customer' + * Body: + * 'The customer has requested /{{interviewType}} with {{candidateName}} for {{jobName}}.' + * + 'In a few minutes you will receive an invitation from our scheduling tool. Please proceed with the invitation to agree on timing.' + * + '

{{customMessage}}' + * + * Note, that the template should be defined in SendGrid. + * The subject & body above (identical to actual SendGrid template) is for reference purposes. + * We won't pass subject & body but only substitutions (replacements in template subject/body). + */ + 'interview-invitation': { + from: config.INTERVIEW_INVITATION_SENDER_EMAIL, + cc: config.INTERVIEW_INVITATION_CC_LIST, + sendgridTemplateId: config.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID } } diff --git a/data/demo-data.json b/data/demo-data.json index 8b5c7211..d34d0aed 100644 --- a/data/demo-data.json +++ b/data/demo-data.json @@ -133,6 +133,31 @@ "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "createdAt": "2021-01-28T19:41:35.098Z", "updatedAt": "2021-01-28T19:41:42.124Z" + }, + { + "id": "1324da27-9d7d-47d8-a04e-9fb3f35a67fa", + "projectId": 111, + "externalId": "88774632", + "description": "Dummy Description", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": 1, + "numPositions": 13, + "resourceType": "Dummy Resource Type", + "rateType": "hourly", + "workload": "full-time", + "skills": [ + "23e00d92-207a-4b5b-b3c9-4c5662644941", + "7d076384-ccf6-4e43-a45d-1b24b1e624aa", + "cbac57a3-7180-4316-8769-73af64893158", + "a2b4bc11-c641-4a19-9eb7-33980378f82e" + ], + "status": "in-review", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-04-14T08:46:17.739Z", + "updatedAt": "2021-04-14T08:46:23.311Z" } ], "JobCandidate": [ @@ -146,7 +171,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:05.723Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "7ff45b8f-2b71-4510-b760-8dfa62e79504", @@ -158,7 +184,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:11.598Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "91d63d5f-01d5-419e-89df-6117ea92f535", @@ -170,7 +197,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:18.066Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "257f98d9-45f7-4e13-a6c2-d7e7b6efc9fe", @@ -182,7 +210,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:24.095Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "a01852d0-fa08-410c-b97b-67580ce62215", @@ -194,7 +223,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:29.734Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "2fd7ca69-c8ec-4bf3-a7f3-655fbfe3e7df", @@ -206,7 +236,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:44.728Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "f0023058-2996-4bba-8c5f-d09a7023be38", @@ -218,7 +249,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:50.619Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "a189b34d-acde-4633-b18b-f7a34d7c5a74", @@ -230,7 +262,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:37:56.456Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "5191a860-4327-4c50-b76b-84beba04519b", @@ -242,7 +275,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "createdAt": "2021-01-28T19:36:51.222Z", - "updatedAt": "2021-01-28T19:38:02.293Z" + "updatedAt": "2021-01-28T19:38:02.293Z", + "interviews": [] }, { "id": "e6d9635c-b122-4f69-9285-09fb1ab30106", @@ -254,7 +288,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "createdAt": "2021-01-28T19:36:58.774Z", - "updatedAt": "2021-01-28T19:38:13.553Z" + "updatedAt": "2021-01-28T19:38:13.553Z", + "interviews": [] }, { "id": "f67b155e-0f09-4fdd-89a7-d79c5e46cac6", @@ -266,7 +301,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:38:38.332Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "8ffd33d3-4a43-4719-aee4-8e46be1d8f1c", @@ -278,7 +314,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:38:43.967Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "2b8ba549-8878-43d6-ad5f-6a66e3b9d6c9", @@ -290,7 +327,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:38:50.106Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "ae5a81ec-5d05-43c4-8253-847d91a54711", @@ -302,7 +340,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-01-28T19:38:55.734Z", - "updatedAt": "2021-03-30T19:11:05.043Z" + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] }, { "id": "85d6649e-2682-4904-9480-a77b72fef27d", @@ -314,7 +353,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "00000000-0000-0000-0000-000000000000", "createdAt": "2021-01-28T19:38:30.856Z", - "updatedAt": "2021-01-28T19:40:27.209Z" + "updatedAt": "2021-01-28T19:40:27.209Z", + "interviews": [] }, { "id": "922dfce3-4e06-4387-9fdb-64f70675e86b", @@ -326,7 +366,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "00000000-0000-0000-0000-000000000000", "createdAt": "2021-01-28T19:39:02.435Z", - "updatedAt": "2021-01-28T19:40:49.349Z" + "updatedAt": "2021-01-28T19:40:49.349Z", + "interviews": [] }, { "id": "c26c38e2-a47d-405b-abc6-fe62a739561c", @@ -338,7 +379,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "00000000-0000-0000-0000-000000000000", "createdAt": "2021-01-28T19:39:08.233Z", - "updatedAt": "2021-01-28T19:40:53.659Z" + "updatedAt": "2021-01-28T19:40:53.659Z", + "interviews": [] }, { "id": "7bef2b37-e1ee-4638-bfc1-c911787ac955", @@ -350,7 +392,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "00000000-0000-0000-0000-000000000000", "createdAt": "2021-01-28T19:39:13.469Z", - "updatedAt": "2021-01-28T19:40:57.999Z" + "updatedAt": "2021-01-28T19:40:57.999Z", + "interviews": [] }, { "id": "e9716139-1f40-4bf1-9f8a-77ae4bcc621e", @@ -362,7 +405,8 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "00000000-0000-0000-0000-000000000000", "createdAt": "2021-01-28T19:39:19.215Z", - "updatedAt": "2021-01-28T19:41:01.953Z" + "updatedAt": "2021-01-28T19:41:01.953Z", + "interviews": [] }, { "id": "a1731d01-eac9-4eff-8e5a-8a3c99bc66e0", @@ -374,7 +418,48 @@ "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": "00000000-0000-0000-0000-000000000000", "createdAt": "2021-01-28T19:39:24.625Z", - "updatedAt": "2021-01-28T19:41:06.370Z" + "updatedAt": "2021-01-28T19:41:06.370Z", + "interviews": [] + }, + { + "id": "25787cb2-d876-4883-b533-d5e628d213ce", + "jobId": "1324da27-9d7d-47d8-a04e-9fb3f35a67fa", + "userId": "95e7970f-12b4-43b7-ab35-38c34bf033c7", + "status": "open", + "externalId": "88774631", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T08:46:23.250Z", + "updatedAt": "2021-04-14T08:46:23.250Z", + "interviews": [ + { + "id": "81f03238-1ce2-4d3d-80c5-5ecd5e7e94a2", + "jobCandidateId": "25787cb2-d876-4883-b533-d5e628d213ce", + "googleCalendarId": "dummyId", + "customMessage": "This is a custom message", + "xaiTemplate": "30-min-interview", + "round": 1, + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T08:46:34.597Z", + "updatedAt": "2021-04-14T08:46:34.597Z" + }, + { + "id": "75363f1d-46c3-4261-9c21-70019f90a61a", + "jobCandidateId": "25787cb2-d876-4883-b533-d5e628d213ce", + "googleCalendarId": "dummyId", + "customMessage": "This is a custom message", + "xaiTemplate": "30-min-interview", + "round": 2, + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T08:50:15.109Z", + "updatedAt": "2021-04-14T08:50:15.109Z" + } + ] } ], "ResourceBooking": [ @@ -2298,4 +2383,4 @@ "updatedAt": null } ] -} \ No newline at end of file +} diff --git a/docs/Topcoder-bookings-api.postman_collection.json b/docs/Topcoder-bookings-api.postman_collection.json index f7bfc83f..3d0a9670 100644 --- a/docs/Topcoder-bookings-api.postman_collection.json +++ b/docs/Topcoder-bookings-api.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "5eb08b17-a20b-4223-9a24-49fb150f51b2", + "_postman_id": "2ec8ba88-98dd-4719-8e72-53ed706f071c", "name": "Topcoder-bookings-api", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, @@ -1886,6 +1886,78 @@ }, "response": [] }, + { + "name": "get job candidate with m2m (read jobCandidate & interview) - included interviews", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_jobCandidate_read_interviews}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, + { + "name": "get job candidate with m2m (read jobCandidate & all interview) - included interviews", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_jobCandidates_all_interviews}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, + { + "name": "get job candidate with m2m (read jobCandidate) - interviews not included", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_job_candidate}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, { "name": "get job candidate with booking manager from db", "request": { @@ -2095,14 +2167,14 @@ "response": [] }, { - "name": "search job candidates with connect user", + "name": "search job candidates with m2m (read jobCandidate & read interview) - included interviews", "request": { "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_m2m_read_jobCandidate_read_interviews}}" } ], "url": { @@ -2160,18 +2232,18 @@ "response": [] }, { - "name": "search job candidates with member", + "name": "search job candidates with m2m (read jobCandidate & all interview) - included interviews", "request": { "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_m2m_read_jobCandidates_all_interviews}}" } ], "url": { - "raw": "{{URL}}/jobCandidates?sortBy=id&sortOrder=asc", + "raw": "{{URL}}/jobCandidates", "host": [ "{{URL}}" ], @@ -2191,11 +2263,13 @@ }, { "key": "sortBy", - "value": "id" + "value": "id", + "disabled": true }, { "key": "sortOrder", - "value": "asc" + "value": "asc", + "disabled": true }, { "key": "jobId", @@ -2223,18 +2297,18 @@ "response": [] }, { - "name": "search job candidates with invalid token", + "name": "search job candidates with m2m (read jobCandidate) - interviews not included", "request": { "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_m2m_read_job_candidate}}" } ], "url": { - "raw": "{{URL}}/jobCandidates?sortBy=id&sortOrder=asc", + "raw": "{{URL}}/jobCandidates", "host": [ "{{URL}}" ], @@ -2254,11 +2328,13 @@ }, { "key": "sortBy", - "value": "id" + "value": "id", + "disabled": true }, { "key": "sortOrder", - "value": "asc" + "value": "asc", + "disabled": true }, { "key": "jobId", @@ -2286,124 +2362,315 @@ "response": [] }, { - "name": "put job candidate with booking manager", + "name": "search job candidates with connect user", "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}" } ], - "body": { - "mode": "raw", - "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "raw": "{{URL}}/jobCandidates", "host": [ "{{URL}}" ], "path": [ - "jobCandidates", - "{{jobCandidateId}}" + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "asc", + "disabled": true + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "shortlist", + "disabled": true + }, + { + "key": "externalId", + "value": "300234321", + "disabled": true + } ] } }, "response": [] }, { - "name": "put job candidate with m2m update", + "name": "search job candidates with member", "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_m2m_update_job_candidate}}" + "value": "Bearer {{token_member}}" } ], - "body": { - "mode": "raw", - "raw": "{\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates?sortBy=id&sortOrder=asc", "host": [ "{{URL}}" ], "path": [ - "jobCandidates", - "{{jobCandidateIdCreatedByM2M}}" + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "shortlist", + "disabled": true + }, + { + "key": "externalId", + "value": "300234321", + "disabled": true + } ] } }, "response": [] }, { - "name": "put job candidate with connect user", + "name": "search job candidates with invalid token", "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer invalid_token" } ], - "body": { - "mode": "raw", - "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "raw": "{{URL}}/jobCandidates?sortBy=id&sortOrder=asc", "host": [ "{{URL}}" ], "path": [ - "jobCandidates", - "{{jobCandidateId}}" - ] - } - }, - "response": [] - }, - { - "name": "put job candidate with member", - "request": { - "method": "PUT", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "shortlist", + "disabled": true + }, + { + "key": "externalId", + "value": "300234321", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "put job candidate with booking manager", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, + { + "name": "put job candidate with m2m update", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_job_candidate}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "put job candidate with connect user", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, + { + "name": "put job candidate with member", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", "host": [ @@ -2816,7 +3083,7 @@ ] }, { - "name": "Resource Bookings", + "name": "Interviews", "item": [ { "name": "Before Test", @@ -2829,7 +3096,7 @@ "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", " if(pm.response.status === \"OK\"){\r", " const response = pm.response.json()\r", " pm.environment.set(\"jobId\", response.id);\r", @@ -2851,7 +3118,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", "options": { "raw": { "language": "json" @@ -2871,14 +3138,19 @@ "response": [] }, { - "name": "create job with m2m", + "name": "create job candidate", "event": [ { "listen": "test", "script": { "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"jobIdCreatedByM2M\",data.id);" + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"jobCandidateId\", response.id);\r", + " }\r", + "});" ], "type": "text/javascript" } @@ -2889,13 +3161,63 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_m2m_create_job}}", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\",\n \"externalId\": \"88774631\",\n \"resume\": \"http://example.com\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + }, + { + "name": "Create completed interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"completedInterviewJobCandidateId\", response.jobCandidateId);\r", + " pm.environment.set(\"completedInterviewRound\", response.round);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"status\": \"Completed\"\r\n}", "options": { "raw": { "language": "json" @@ -2903,12 +3225,14 @@ } }, "url": { - "raw": "{{URL}}/jobs", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "jobs" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, @@ -2917,17 +3241,17 @@ ] }, { - "name": "create resource booking with booking manager", + "name": "Request interview", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", " if(pm.response.status === \"OK\"){\r", " const response = pm.response.json()\r", - " pm.environment.set(\"resourceBookingId\", response.id);\r", + " pm.environment.set(\"interviewRound\", response.round);\r", " }\r", "});" ], @@ -2936,17 +3260,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-10-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"attendeesList\": [\"attendee1@yopmail.com\", \"attendee2@yopmail.com\"],\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -2954,19 +3278,21 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search work periods of newly created resource booking", + "name": "Request interview for the same jobCandidateId - should increment round", "event": [ { "listen": "test", @@ -2974,6 +3300,10 @@ "exec": [ "pm.test('Status code is 200', function () {\r", " pm.response.to.have.status(200);\r", + " const response = pm.response.json();\r", + " const lastRound = pm.environment.get(\"interviewRound\");\r", + " pm.expect(response.round).to.eq(lastRound + 1);\r", + " pm.environment.set(\"interviewRound\", response.round);\r", "});" ], "type": "text/javascript" @@ -2981,92 +3311,50 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingId}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with m2m create", + "name": "Request interview without status - should take default status", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", " if(pm.response.status === \"OK\"){\r", " const response = pm.response.json()\r", - " pm.environment.set(\"resourceBookingIdCreatedByM2M\", response.id);\r", + " pm.environment.set(\"interviewRound\", response.round);\r", + " pm.expect(response.status).to.eq(\"Scheduling\")\r", " }\r", "});" ], @@ -3075,17 +3363,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_create_resource_booking}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27T04:17:23.131Z\",\r\n \"endDate\": \"2021-01-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", "options": { "raw": { "language": "json" @@ -3093,26 +3381,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search work periods of newly created resource booking", + "name": "Request interview with invalid status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", "});" ], "type": "text/javascript" @@ -3120,91 +3412,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"status\": \"xxxx\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingIdCreatedByM2M}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with connect user", + "name": "Request interview with attendeesList", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.attendeesList[0]).to.eq(\"attendee1@yopmail.com\")\r", + " pm.expect(response.attendeesList[1]).to.eq(\"attendee2@yopmail.com\")\r", "});" ], "type": "text/javascript" @@ -3212,17 +3462,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"attendeesList\": [\"attendee1@yopmail.com\", \"attendee2@yopmail.com\"]\r\n}", "options": { "raw": { "language": "json" @@ -3230,28 +3480,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with member", + "name": "Request interview with invalid attendeesList", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.attendeesList\\\" must be an array\")\r", "});" ], "type": "text/javascript" @@ -3259,17 +3511,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"attendeesList\": \"asddd\"\r\n}", "options": { "raw": { "language": "json" @@ -3277,19 +3529,21 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with user id not exist", + "name": "Request interview with invalid attendee email", "event": [ { "listen": "test", @@ -3298,7 +3552,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.attendeesList[0]\\\" must be a valid email\")\r", "});" ], "type": "text/javascript" @@ -3306,17 +3560,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"attendeesList\": [\"asdas\"]\r\n}", "options": { "raw": { "language": "json" @@ -3324,28 +3578,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with invalid token", + "name": "Request interview with round - should not accept", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.round\\\" is not allowed\")\r", "});" ], "type": "text/javascript" @@ -3353,17 +3609,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"round\": 1\r\n}", "options": { "raw": { "language": "json" @@ -3371,26 +3627,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with booking manager", + "name": "Request interview with startTimestamp - should not accept", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.startTimestamp\\\" is not allowed\")\r", "});" ], "type": "text/javascript" @@ -3398,36 +3658,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"startTimestamp\": \"2021-04-17\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with m2m read", + "name": "Request interview without xaiTemplate - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.xaiTemplate\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -3435,36 +3707,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_read_resource_booking}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"Requested\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with booking manager from db", + "name": "Request interview with invalid xaiTemplate", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.xaiTemplate\\\" must be one of [30-min-interview, 60-min-interview]\")\r", "});" ], "type": "text/javascript" @@ -3472,42 +3756,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"asdas\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fromDb=true", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" - ], - "query": [ - { - "key": "fromDb", - "value": "true" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with connect user", + "name": "Request interview with non-existing jobCandidate", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(404);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"The job candidate with id=9105f597-f9d5-49c0-9cbf-9a0cbda47260 doesn't exist.\")\r", "});" ], "type": "text/javascript" @@ -3515,38 +3805,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/9105f597-f9d5-49c0-9cbf-9a0cbda47260/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "9105f597-f9d5-49c0-9cbf-9a0cbda47260", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with member", + "name": "Request interview with non-existing userId in token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"userId: 8547899 the user is not a member of project 111\")\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", "});" ], "type": "text/javascript" @@ -3554,29 +3854,39 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_userId_not_exist}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with booking manager", + "name": "Request interview with administrator", "event": [ { "listen": "test", @@ -3591,75 +3901,39 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "status", - "value": "assigned", - "disabled": true - }, - { - "key": "projectIds", - "value": "111, 16705", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with m2m all", + "name": "Request interview with booking manager", "event": [ { "listen": "test", @@ -3674,70 +3948,39 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_all_resource_booking}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "status", - "value": "assigned", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with connect user", + "name": "Request interview with m2m (all interview scope)", "event": [ { "listen": "test", @@ -3752,143 +3995,95 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with member", + "name": "Request interview with m2m (create interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "" - ], + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], "type": "text/javascript" } } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with invalid token", + "name": "Request interview with m2m (read interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -3896,71 +4091,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with booking manager", + "name": "Request interview with m2m (update interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -3968,17 +4140,17 @@ } ], "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-26T04:17:23.131Z\",\r\n \"endDate\": \"2020-11-29T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", "options": { "raw": { "language": "json" @@ -3986,27 +4158,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search extended work periods of resource booking", + "name": "Request interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4014,89 +4189,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingId}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with m2m update", + "name": "Request interview with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4104,17 +4238,17 @@ } ], "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_update_resource_booking}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27T04:17:23.131Z\",\r\n \"endDate\": \"2021-01-10T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", "options": { "raw": { "language": "json" @@ -4122,27 +4256,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search reduced work periods of resource booking", + "name": "Request interview with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4150,91 +4287,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingIdCreatedByM2M}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with connect user", + "name": "Request interview without token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -4242,17 +4336,11 @@ } ], "request": { - "method": "PUT", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" - } - ], + "method": "PATCH", + "header": [], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", "options": { "raw": { "language": "json" @@ -4260,29 +4348,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with member", + "name": "Request interview with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -4290,17 +4379,17 @@ } ], "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer invalid_token", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\"\r\n}", "options": { "raw": { "language": "json" @@ -4308,29 +4397,28 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with user id not exist", + "name": "Get interview by round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -4338,47 +4426,38 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "put resource booking with invalid token", + "name": "Get interview fromDb by round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -4386,45 +4465,46 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}?fromDb=true", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" + ], + "query": [ + { + "key": "fromDb", + "value": "true" + } ] } }, "response": [] }, { - "name": "patch resource booking with booking manager", + "name": "Get interview by negative round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"round\\\" must be a positive number\")\r", "});" ], "type": "text/javascript" @@ -4432,45 +4512,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-30T04:17:23.131Z\",\r\n \"endDate\": \"2020-11-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/-1", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "-1" ] } }, "response": [] }, { - "name": "patch resource booking with m2m update", + "name": "Get interview by round=0", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"round\\\" must be a positive number\")\r", "});" ], "type": "text/javascript" @@ -4478,47 +4553,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_update_resource_booking}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-12-30T04:17:23.131Z\",\r\n \"endDate\": \"2021-02-10T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/0", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "0" ] } }, "response": [] }, { - "name": "patch resource booking with connect user", + "name": "Get interview by non-existing round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(404);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Interview doesn't exist with round: 999\")\r", "});" ], "type": "text/javascript" @@ -4526,47 +4594,38 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/999", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "999" ] } }, "response": [] }, { - "name": "patch resource booking with member", + "name": "Get interview with administrator", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -4574,47 +4633,38 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking with user id not exist", + "name": "Get interview with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -4622,47 +4672,38 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking with invalid token", + "name": "Get interview with m2m (all interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -4670,38 +4711,31 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "search work periods", + "name": "Get interview with m2m (read interview scope)", "event": [ { "listen": "test", @@ -4709,8 +4743,6 @@ "exec": [ "pm.test('Status code is 200', function () {\r", " pm.response.to.have.status(200);\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"workPeriodIdForPaid\", response[0].id);\r", "});" ], "type": "text/javascript" @@ -4722,84 +4754,36 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods?perPage=1&sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "1" - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingId}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch work period set status to completed", + "name": "Get interview with m2m (create interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4807,45 +4791,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"paymentStatus\": \"completed\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdForPaid}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdForPaid}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking to cancelled", + "name": "Get interview with m2m (update interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4853,45 +4832,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking to reduce", + "name": "Get interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4899,38 +4873,31 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"startDate\": \"2020-10-04T04:17:23.131Z\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "delete resource booking with member", + "name": "Get interview with connect user", "event": [ { "listen": "test", @@ -4947,38 +4914,31 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "delete resource booking with connect user", + "name": "Get interview with member", "event": [ { "listen": "test", @@ -4995,45 +4955,40 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "delete resource booking with booking manager", + "name": "Get interview by round without token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -5041,45 +4996,34 @@ } ], "request": { - "method": "DELETE", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" - } - ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, + "method": "GET", + "header": [], "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/1", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "1" ] } }, "response": [] }, { - "name": "delete resource booking with m2m delete", + "name": "Get interview by round with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 204', function () {\r", - " pm.response.to.have.status(204);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -5087,47 +5031,38 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_delete_resource_booking}}" + "value": "Bearer invalid_token", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/1", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "1" ] } }, "response": [] }, { - "name": "delete resource booking with invalid token", + "name": "Update interview", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -5135,17 +5070,17 @@ } ], "request": { - "method": "DELETE", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "", + "raw": "{\r\n \"googleCalendarId\": \"dummyIdXX\",\r\n \"customMessage\": \"This is the updated message\"\r\n}", "options": { "raw": { "language": "json" @@ -5153,139 +5088,31 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] - } - ] - }, - { - "name": "Work Periods", - "item": [ - { - "name": "Before Test", - "item": [ - { - "name": "create job", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"jobId\", response.id);\r", - " }\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobs", - "host": [ - "{{URL}}" - ], - "path": [ - "jobs" - ] - } - }, - "response": [] - }, - { - "name": "create resource booking", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"resourceBookingId\", response.id);\r", - " }\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/resourceBookings", - "host": [ - "{{URL}}" - ], - "path": [ - "resourceBookings" - ] - } - }, - "response": [] - } - ] }, { - "name": "create work period with booking manager", + "name": "Update interview with empty payload", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"workPeriodId\", response.id);\r", - " }\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data\\\" must have at least 1 key\")\r", "});" ], "type": "text/javascript" @@ -5293,17 +5120,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{}", "options": { "raw": { "language": "json" @@ -5311,30 +5138,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with m2m create", + "name": "Update interview with invalid startTimestamp", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"workPeriodIdCreatedByM2M\", response.id);\r", - " }\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" must be a valid date\")\r", "});" ], "type": "text/javascript" @@ -5342,17 +5170,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_create_work_period}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"xxx\"\r\n}", "options": { "raw": { "language": "json" @@ -5360,28 +5188,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with connect user", + "name": "Update interview with past startTimestamp", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" must be greater than \\\"now\\\"\")\r", "});" ], "type": "text/javascript" @@ -5389,17 +5220,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2021-04-01\"\r\n}", "options": { "raw": { "language": "json" @@ -5407,28 +5238,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with member", + "name": "Update interview with invalid status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", "});" ], "type": "text/javascript" @@ -5436,17 +5270,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"status\": \"xxx\"\r\n}", "options": { "raw": { "language": "json" @@ -5454,19 +5288,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with user id not exist", + "name": "Update interview with invalid xaiTemplate", "event": [ { "listen": "test", @@ -5475,7 +5312,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.xaiTemplate\\\" must be one of [30-min-interview, 60-min-interview]\")\r", "});" ], "type": "text/javascript" @@ -5483,17 +5320,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"xxx\"\r\n}", "options": { "raw": { "language": "json" @@ -5501,28 +5338,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid token", + "name": "Update interview status to Scheduled without googleCalendarId", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.googleCalendarId\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5530,17 +5370,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2030-12-12\",\r\n \"status\": \"Scheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5548,19 +5388,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with missing parameter 1", + "name": "Update interview status to Scheduled without startTimestamp", "event": [ { "listen": "test", @@ -5569,7 +5412,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5577,17 +5420,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\",\r\n \"status\": \"Scheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5595,19 +5438,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with missing parameter 2", + "name": "Update interview status to Rescheduled without googleCalendarId", "event": [ { "listen": "test", @@ -5616,7 +5462,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.endDate\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.googleCalendarId\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5624,17 +5470,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2030-12-12\",\r\n \"status\": \"Rescheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5642,19 +5488,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with missing parameter 3", + "name": "Update interview status to Rescheduled without startTimestamp", "event": [ { "listen": "test", @@ -5663,7 +5512,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5671,17 +5520,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\",\r\n \"status\": \"Rescheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5689,19 +5538,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 1", + "name": "Update Completed interview without status", "event": [ { "listen": "test", @@ -5710,7 +5562,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" must be a valid GUID\")\r", + " pm.expect(response.message).to.eq(\"Only the \\\"status\\\" can be updated for Completed interviews.\")\r", "});" ], "type": "text/javascript" @@ -5718,17 +5570,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5736,19 +5588,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{completedInterviewJobCandidateId}}", + "updateInterview", + "{{completedInterviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 2", + "name": "Update Completed interview with additional fields", "event": [ { "listen": "test", @@ -5757,7 +5612,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.startDate\\\" must be in YYYY-MM-DD format\")\r", + " pm.expect(response.message).to.eq(\"Only the \\\"status\\\" can be updated for Completed interviews.\")\r", "});" ], "type": "text/javascript" @@ -5765,17 +5620,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\",\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -5783,28 +5638,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{completedInterviewJobCandidateId}}", + "updateInterview", + "{{completedInterviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 3", + "name": "Update Completed interview with only status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + " pm.expect(response.status).to.eq(\"Scheduling\")\r", "});" ], "type": "text/javascript" @@ -5812,17 +5670,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -5830,28 +5688,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{completedInterviewJobCandidateId}}", + "updateInterview", + "{{completedInterviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 4", + "name": "Update interview with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -5859,17 +5718,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5877,28 +5736,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 5", + "name": "Update interview with administrator", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.daysWorked\\\" must be a number\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -5906,17 +5766,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5924,28 +5784,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 6", + "name": "Update interview with m2m (all interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-07, 2021-03-13) already exists.`)\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -5953,17 +5814,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5971,28 +5832,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 7", + "name": "Update interview with m2m (update interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -6000,17 +5862,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -6018,26 +5880,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with booking manager", + "name": "Update interview with m2m (read interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6045,36 +5912,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with m2m read 1", + "name": "Update interview with m2m (create interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6082,36 +5962,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_read_work_period}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with m2m read 2", + "name": "Update interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6119,36 +6012,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_read_work_period_and_payment}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with booking manager from db", + "name": "Update interview with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6156,42 +6062,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}?fromDb=true", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" - ], - "query": [ - { - "key": "fromDb", - "value": "true" - } + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with connect user", + "name": "Update interview with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6199,29 +6112,40 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with member", + "name": "Update interview without token", "event": [ { "listen": "test", @@ -6229,6 +6153,8 @@ "exec": [ "pm.test('Status code is 401', function () {\r", " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -6236,36 +6162,91 @@ } ], "request": { - "method": "GET", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" - } - ], + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "search work periods with booking manager", + "name": "Update interview with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer invalid_key", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" + ] + } + }, + "response": [] + }, + { + "name": "Search interviews", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6277,32 +6258,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "35", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6311,38 +6284,18 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6351,14 +6304,16 @@ "response": [] }, { - "name": "search work periods with m2m all 1", + "name": "Search interviews by invalid status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", "});" ], "type": "text/javascript" @@ -6370,32 +6325,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_all_work_period}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?status=xxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6404,39 +6351,18 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "16843", - "disabled": true + "key": "status", + "value": "xxx" } ] } @@ -6444,14 +6370,16 @@ "response": [] }, { - "name": "search work periods with m2m all 2", + "name": "Search interviews by invalid createdAt", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.createdAt\\\" must be a valid date\")\r", "});" ], "type": "text/javascript" @@ -6463,32 +6391,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_all_work_period_and_payment}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?createdAt=xxxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6497,38 +6417,17 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true + "key": "createdAt", + "value": "xxxx" }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6537,14 +6436,16 @@ "response": [] }, { - "name": "search work periods with connect user", + "name": "Search interviews by invalid updatedAt", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.updatedAt\\\" must be a valid date\")\r", "});" ], "type": "text/javascript" @@ -6556,32 +6457,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?updatedAt=xxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6590,38 +6483,17 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "endDate", - "value": "2021-03-20", - "disabled": true + "key": "updatedAt", + "value": "xxx" }, { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6630,78 +6502,64 @@ "response": [] }, { - "name": "search work periods with member", + "name": "Search interviews by invalid sortOrder", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.sortOrder\\\" must be one of [desc, asc]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?sortOrder=xxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true + "value": "xxx" }, { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6710,14 +6568,16 @@ "response": [] }, { - "name": "search work periods with invalid token", + "name": "Search interviews by invalid sortBy", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.sortBy\\\" must be one of [round, createdAt, updatedAt]\")\r", "});" ], "type": "text/javascript" @@ -6729,33 +6589,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?sortBy=xxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", - "disabled": true + "value": "xxx" }, { "key": "sortOrder", @@ -6763,38 +6614,18 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "111", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6803,14 +6634,14 @@ "response": [] }, { - "name": "put work period with booking manager", + "name": "Search interviews with administrator", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6818,45 +6649,64 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with m2m update", + "name": "Search interviews with booking manager", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6864,47 +6714,64 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_update_work_period}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with connect user", + "name": "Search interviews with m2m (all interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6912,47 +6779,64 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with member", + "name": "Search interviews with m2m (read interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6960,47 +6844,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with user id not exist", + "name": "Search interviews with m2m (create interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7008,47 +6911,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with invalid token", + "name": "Search interviews with m2m (update interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7056,47 +6978,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with missing parameter 1", + "name": "Search interviews with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7104,47 +7045,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with missing parameter 2", + "name": "Search interviews with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.endDate\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7152,47 +7112,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with missing parameter 3", + "name": "Search interviews with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.paymentStatus\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7200,95 +7179,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" - ] - } - }, - "response": [] - }, - { - "name": "put work period with invalid parameter 1", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" must be a valid GUID\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", - "host": [ - "{{URL}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], - "path": [ - "work-periods", - "{{workPeriodId}}" + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with invalid parameter 2", + "name": "Search interviews without token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.startDate\\\" must be in YYYY-MM-DD format\")\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -7296,47 +7246,33 @@ } ], "request": { - "method": "PUT", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, + "method": "GET", + "header": [], "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ] } }, "response": [] }, { - "name": "put work period with invalid parameter 3", + "name": "Search interviews with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -7344,47 +7280,144 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer invalid_token", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ] } }, "response": [] + } + ] + }, + { + "name": "Resource Bookings", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"jobId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create job with m2m", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"jobIdCreatedByM2M\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_m2m_create_job}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + } + ] }, { - "name": "put work period with invalid parameter 4", + "name": "create resource booking with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"resourceBookingId\", response.id);\r", + " }\r", "});" ], "type": "text/javascript" @@ -7392,7 +7425,7 @@ } ], "request": { - "method": "PUT", + "method": "POST", "header": [ { "key": "Authorization", @@ -7402,7 +7435,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-10-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -7410,29 +7443,26 @@ } }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "put work period with invalid parameter 5", + "name": "search work periods of newly created resource booking", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.daysWorked\\\" must be a number\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -7440,7 +7470,7 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", @@ -7448,39 +7478,85 @@ "value": "Bearer {{token_bookingManager}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingId}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with invalid parameter 6", + "name": "create resource booking with m2m create", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-14, 2021-03-20) already exists.`)\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"resourceBookingIdCreatedByM2M\", response.id);\r", + " }\r", "});" ], "type": "text/javascript" @@ -7488,17 +7564,17 @@ } ], "request": { - "method": "PUT", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_create_resource_booking}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27T04:17:23.131Z\",\r\n \"endDate\": \"2021-01-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -7506,29 +7582,26 @@ } }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "put work period with invalid parameter 7", + "name": "search work periods of newly created resource booking", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -7536,7 +7609,7 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", @@ -7544,37 +7617,83 @@ "value": "Bearer {{token_bookingManager}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingIdCreatedByM2M}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } ] } }, "response": [] }, { - "name": "patch work period with booking manager", + "name": "create resource booking with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7582,17 +7701,17 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -7600,27 +7719,28 @@ } }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "patch work period with m2m update", + "name": "create resource booking with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7628,17 +7748,17 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_m2m_update_work_period}}" + "value": "Bearer {{token_member}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -7646,29 +7766,28 @@ } }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdCreatedByM2M}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "patch work period with connect user", + "name": "create resource booking with user id not exist", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", "});" ], "type": "text/javascript" @@ -7676,17 +7795,17 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_userId_not_exist}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -7694,29 +7813,28 @@ } }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "patch work period with member", + "name": "create resource booking with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -7724,17 +7842,17 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer invalid_token" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -7742,29 +7860,26 @@ } }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "patch work period with user id not exist", + "name": "get resource booking with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -7772,47 +7887,36 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings", + "{{resourceBookingId}}" ] } }, "response": [] }, { - "name": "patch work period with invalid token", + "name": "get resource booking with m2m read", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -7820,47 +7924,36 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_m2m_read_resource_booking}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" ] } }, "response": [] }, { - "name": "patch work period with invalid parameter 1", + "name": "get resource booking with booking manager from db", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" must be a valid GUID\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -7868,7 +7961,7 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", @@ -7876,39 +7969,34 @@ "value": "Bearer {{token_bookingManager}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fromDb=true", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings", + "{{resourceBookingId}}" + ], + "query": [ + { + "key": "fromDb", + "value": "true" + } ] } }, "response": [] }, { - "name": "patch work period with invalid parameter 2", + "name": "get resource booking with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.startDate\\\" must be in YYYY-MM-DD format\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -7916,47 +8004,38 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings", + "{{resourceBookingId}}" ] } }, "response": [] }, { - "name": "patch work period with invalid parameter 3", + "name": "get resource booking with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + " pm.expect(response.message).to.eq(\"userId: 8547899 the user is not a member of project 111\")\r", "});" ], "type": "text/javascript" @@ -7964,47 +8043,36 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_member}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings", + "{{resourceBookingId}}" ] } }, "response": [] }, { - "name": "patch work period with invalid parameter 4", + "name": "search resource bookings with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -8012,7 +8080,7 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", @@ -8020,39 +8088,74 @@ "value": "Bearer {{token_bookingManager}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "status", + "value": "assigned", + "disabled": true + }, + { + "key": "projectIds", + "value": "111, 16705", + "disabled": true + } ] } }, "response": [] }, { - "name": "patch work period with invalid parameter 5", + "name": "search resource bookings with m2m all", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.daysWorked\\\" must be a number\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -8060,47 +8163,77 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_all_resource_booking}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "status", + "value": "assigned", + "disabled": true + } ] } }, "response": [] }, { - "name": "patch work period with invalid parameter 6", + "name": "search resource bookings with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-14, 2021-03-20) already exists.`)\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -8108,95 +8241,143 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings?sortOrder=desc", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } ] } }, "response": [] }, { - "name": "patch work period with invalid parameter 7", + "name": "search resource bookings with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", - "});" + "" ], "type": "text/javascript" } } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_member}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings?sortOrder=desc", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } ] } }, "response": [] }, { - "name": "delete work period with member", + "name": "search resource bookings with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -8204,47 +8385,71 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer invalid_token" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings?sortOrder=desc", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } ] } }, "response": [] }, { - "name": "delete work period with connect user", + "name": "put resource booking with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -8252,17 +8457,17 @@ } ], "request": { - "method": "DELETE", + "method": "PUT", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}" } ], "body": { "mode": "raw", - "raw": "", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-26T04:17:23.131Z\",\r\n \"endDate\": \"2020-11-29T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", "options": { "raw": { "language": "json" @@ -8270,27 +8475,27 @@ } }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "resourceBookings", + "{{resourceBookingId}}" ] } }, "response": [] }, { - "name": "delete work period with booking manager", + "name": "search extended work periods of resource booking", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 204', function () {\r", - " pm.response.to.have.status(204);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -8298,7 +8503,7 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", @@ -8306,53 +8511,4337 @@ "value": "Bearer {{token_bookingManager}}" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" - ] - } - }, - "response": [] - }, - { - "name": "delete work period with m2m delete", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 204', function () {\r", - " pm.response.to.have.status(204);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_delete_work_period}}" - } - ], - "body": { + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingId}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with m2m update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_resource_booking}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27T04:17:23.131Z\",\r\n \"endDate\": \"2021-01-10T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "search reduced work periods of resource booking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingIdCreatedByM2M}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-30T04:17:23.131Z\",\r\n \"endDate\": \"2020-11-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with m2m update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_resource_booking}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-12-30T04:17:23.131Z\",\r\n \"endDate\": \"2021-02-10T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "search work periods", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"workPeriodIdForPaid\", response[0].id);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods?perPage=1&sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1" + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingId}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "patch work period set status to completed", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"paymentStatus\": \"completed\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdForPaid}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdForPaid}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking to cancelled", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking to reduce", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"startDate\": \"2020-10-04T04:17:23.131Z\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with m2m delete", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 204', function () {\r", + " pm.response.to.have.status(204);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_delete_resource_booking}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Work Periods", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"jobId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create resource booking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"resourceBookingId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "create work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"workPeriodId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with m2m create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"workPeriodIdCreatedByM2M\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_create_work_period}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with missing parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with missing parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.endDate\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with missing parameter 3", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" must be a valid GUID\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.startDate\\\" must be in YYYY-MM-DD format\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 3", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 4", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 5", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.daysWorked\\\" must be a number\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 6", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-07, 2021-03-13) already exists.`)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 7", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "get work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with m2m read 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_work_period}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with m2m read 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_work_period_and_payment}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with booking manager from db", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}?fromDb=true", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ], + "query": [ + { + "key": "fromDb", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "get work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "search work periods with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "35", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with m2m all 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_work_period}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with m2m all 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_work_period_and_payment}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with member", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "111", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "put work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with m2m update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_work_period}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with missing parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with missing parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.endDate\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with missing parameter 3", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.paymentStatus\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" must be a valid GUID\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.startDate\\\" must be in YYYY-MM-DD format\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid parameter 3", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid parameter 4", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid parameter 5", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.daysWorked\\\" must be a number\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid parameter 6", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-14, 2021-03-20) already exists.`)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid parameter 7", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with m2m update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_work_period}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" must be a valid GUID\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.startDate\\\" must be in YYYY-MM-DD format\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid parameter 3", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid parameter 4", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid parameter 5", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.daysWorked\\\" must be a number\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid parameter 6", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-14, 2021-03-20) already exists.`)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch work period with invalid parameter 7", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 204', function () {\r", + " pm.response.to.have.status(204);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete work period with m2m delete", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 204', function () {\r", + " pm.response.to.have.status(204);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_delete_work_period}}" + } + ], + "body": { "mode": "raw", "raw": "", "options": { @@ -14581,7 +19070,156 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\"\r\n}", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + }, + { + "name": "✔ get job candidate with administrator", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ search job candidates with administrator", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "asc", + "disabled": true + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "shortlist", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "✔ put job candidate with administrator", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"status\": \"selected\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ patch job candidate with administrator", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"shortlist\"\r\n}", "options": { "raw": { "language": "json" @@ -14589,21 +19227,22 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}" ] } }, "response": [] }, { - "name": "✔ get job candidate with administrator", + "name": "✔ delete job candidate with administrator", "request": { - "method": "GET", + "method": "DELETE", "header": [ { "key": "Authorization", @@ -14611,6 +19250,15 @@ "value": "Bearer {{token_administrator}}" } ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", "host": [ @@ -14623,114 +19271,222 @@ } }, "response": [] + } + ] + }, + { + "name": "Interviews", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_by_administrator\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create job candidate", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_candidate_id_created_by_administrator\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + } + ] }, { - "name": "✔ search job candidates with administrator", + "name": "✔ request interview with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"interview_round_created_by_administrator\", response.round);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "1", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "asc", - "disabled": true - }, - { - "key": "jobId", - "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", - "disabled": true - }, - { - "key": "userId", - "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", - "disabled": true - }, - { - "key": "status", - "value": "shortlist", - "disabled": true - } + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}", + "requestInterview" ] } }, "response": [] }, { - "name": "✔ put job candidate with administrator", + "name": "✔ get interview with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"status\": \"selected\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/interviews/{{interview_round_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_by_administrator}}" + "{{job_candidate_id_created_by_administrator}}", + "interviews", + "{{interview_round_created_by_administrator}}" ] } }, "response": [] }, { - "name": "✔ patch job candidate with administrator", + "name": "✔ update interview with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"shortlist\"\r\n}", + "raw": "{\r\n \"customMessage\": \"updated\"\r\n}", "options": { "raw": { "language": "json" @@ -14738,46 +19494,53 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/updateInterview/{{interview_round_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_by_administrator}}" + "{{job_candidate_id_created_by_administrator}}", + "updateInterview", + "{{interview_round_created_by_administrator}}" ] } }, "response": [] }, { - "name": "✔ delete job candidate with administrator", + "name": "✔ search interviews with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/interviews", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_by_administrator}}" + "{{job_candidate_id_created_by_administrator}}", + "interviews" ] } }, @@ -16303,17 +21066,278 @@ { "name": "✔ put job candidate with member", "request": { - "method": "PUT", + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_member}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"selected\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ patch job candidate with member", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"shortlist\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✘ delete job candidate with member", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Interviews", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_for_member\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create job candidate", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_candidate_id_created_for_member\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + }, + { + "name": "create interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"interview_round_created_for_member\", response.round)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}", + "requestInterview" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "✘ request interview with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_member}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"selected\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -16321,32 +21345,89 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_member}}" + "{{job_candidate_id_created_for_member}}", + "requestInterview" ] } }, "response": [] }, { - "name": "✔ patch job candidate with member", + "name": "✘ get interview with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_member}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/interviews/{{interview_round_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}", + "interviews", + "{{interview_round_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✘ update interview with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"shortlist\"\r\n}", + "raw": "{\r\n \"customMessage\": \"updated\"\r\n}", "options": { "raw": { "language": "json" @@ -16354,46 +21435,55 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/updateInterview/{{interview_round_created_for_member}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_member}}" + "{{job_candidate_id_created_for_member}}", + "updateInterview", + "{{interview_round_created_for_member}}" ] } }, "response": [] }, { - "name": "✘ delete job candidate with member", + "name": "✘ search interviews with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/interviews", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_member}}" + "{{job_candidate_id_created_for_member}}", + "interviews" ] } }, @@ -17343,22 +22433,183 @@ } } }, - "url": { - "raw": "{{URL}}/work-period-payments", - "host": [ - "{{URL}}" - ], - "path": [ - "work-period-payments" - ] + "url": { + "raw": "{{URL}}/work-period-payments", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "✘ create work period payment with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 600,\r\n \"status\": \"completed\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-period-payments", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments" + ] + } + }, + "response": [] + }, + { + "name": "✘ get work period payment with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "url": { + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments", + "{{workPeriodPaymentId_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✘ search work period payments with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "url": { + "raw": "{{URL}}/work-period-payments", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "status", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "workPeriodId", + "value": "{{workPeriodPaymentId_created_for_member}}", + "disabled": true + }, + { + "key": "workPeriodIds", + "value": "{{workPeriodPaymentId_created_for_member}},{{workPeriodPaymentId_created_for_member}}", + "disabled": true + }, + { + "key": "status", + "value": "completed", + "disabled": true } - }, - "response": [] + ] } - ] + }, + "response": [] }, { - "name": "✘ create work period payment with member", + "name": "✘ put work period payment with member", "event": [ { "listen": "test", @@ -17375,7 +22626,7 @@ } ], "request": { - "method": "POST", + "method": "PUT", "header": [ { "key": "Authorization", @@ -17385,7 +22636,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 600,\r\n \"status\": \"completed\"\r\n}", + "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 1600,\r\n \"status\": \"completed\"\r\n}", "options": { "raw": { "language": "json" @@ -17393,19 +22644,20 @@ } }, "url": { - "raw": "{{URL}}/work-period-payments", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments" + "work-period-payments", + "{{workPeriodPaymentId_created_for_member}}" ] } }, "response": [] }, { - "name": "✘ get work period payment with member", + "name": "✘ patch work period payment with member", "event": [ { "listen": "test", @@ -17422,7 +22674,7 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", @@ -17430,6 +22682,15 @@ "value": "Bearer {{token_member_tester1234}}" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 450,\r\n \"status\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", "host": [ @@ -17442,75 +22703,189 @@ } }, "response": [] - }, + } + ] + } + ] + }, + { + "name": "Request with Connect Manager Role", + "item": [ + { + "name": "README", + "item": [ { - "name": "✘ search work period payments with member", + "name": "[STUB] all operations except get/search cause 403 error if manager is not member of project", + "request": { + "method": "LOCK", + "header": [], + "url": { + "raw": "" + } + }, + "response": [] + } + ] + }, + { + "name": "Jobs", + "item": [ + { + "name": "✔ create job with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_by_connect_manager\",data.id);" ], "type": "text/javascript" } } ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "✔ get job with connect manager", "request": { "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "url": { - "raw": "{{URL}}/work-period-payments", + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments" + "jobs", + "{{job_id_created_by_connect_manager}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ search jobs with connect manager", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + } + ], + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" ], "query": [ { "key": "page", - "value": "1", + "value": "0", "disabled": true }, { "key": "perPage", - "value": "5", + "value": "3", "disabled": true }, { "key": "sortBy", - "value": "status", + "value": "id", "disabled": true }, { "key": "sortOrder", - "value": "desc", + "value": "asc", "disabled": true }, { - "key": "workPeriodId", - "value": "{{workPeriodPaymentId_created_for_member}}", + "key": "projectId", + "value": "21", "disabled": true }, { - "key": "workPeriodIds", - "value": "{{workPeriodPaymentId_created_for_member}},{{workPeriodPaymentId_created_for_member}}", + "key": "externalId", + "value": "1212", + "disabled": true + }, + { + "key": "description", + "value": "Dummy", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "resourceType", + "value": "Dummy Resource Type", + "disabled": true + }, + { + "key": "skill", + "value": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", "disabled": true }, { "key": "status", - "value": "completed", + "value": "sourcing", + "disabled": true + }, + { + "key": "workload", + "value": "full-time", + "disabled": true + }, + { + "key": "title", + "value": "dummy", "disabled": true } ] @@ -17519,34 +22894,52 @@ "response": [] }, { - "name": "✘ put work period payment with member", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" + "name": "✔ put job with connect manager", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs", + "{{job_id_created_by_connect_manager}}" + ] } - ], + }, + "response": [] + }, + { + "name": "✔ patch job with connect manager", "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 1600,\r\n \"status\": \"completed\"\r\n}", + "raw": "{\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", "options": { "raw": { "language": "json" @@ -17554,47 +22947,32 @@ } }, "url": { - "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments", - "{{workPeriodPaymentId_created_for_member}}" + "jobs", + "{{job_id_created_by_connect_manager}}" ] } }, "response": [] }, { - "name": "✘ patch work period payment with member", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], + "name": "✘ delete job with connect manager", "request": { - "method": "PATCH", + "method": "DELETE", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 450,\r\n \"status\": \"cancelled\"\r\n}", + "raw": "", "options": { "raw": { "language": "json" @@ -17602,53 +22980,81 @@ } }, "url": { - "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments", - "{{workPeriodPaymentId_created_for_member}}" + "jobs", + "{{job_id_created_by_connect_manager}}" ] } }, "response": [] } ] - } - ] - }, - { - "name": "Request with Connect Manager Role", - "item": [ + }, { - "name": "README", + "name": "Job Candidates", "item": [ { - "name": "[STUB] all operations except get/search cause 403 error if manager is not member of project", - "request": { - "method": "LOCK", - "header": [], - "url": { - "raw": "" + "name": "Before Test", + "item": [ + { + "name": "create job candidate", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_candidate_id_created_for_connect_manager\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] } - }, - "response": [] - } - ] - }, - { - "name": "Jobs", - "item": [ + ] + }, { - "name": "✔ create job with connect manager", + "name": "✘ create job candidate with connect manager", "event": [ { "listen": "test", "script": { "exec": [ "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"job_id_created_by_connect_manager\",data.id);" + "postman.setEnvironmentVariable(\"job_candidate_id_created_by_connect_manager\",data.id);" ], "type": "text/javascript" } @@ -17659,13 +23065,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", - "type": "text" + "type": "text", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", "options": { "raw": { "language": "json" @@ -17673,19 +23079,19 @@ } }, "url": { - "raw": "{{URL}}/jobs", + "raw": "{{URL}}/jobCandidates", "host": [ "{{URL}}" ], "path": [ - "jobs" + "jobCandidates" ] } }, "response": [] }, { - "name": "✔ get job with connect manager", + "name": "✔ get job candidate with connect manager", "request": { "method": "GET", "header": [ @@ -17696,20 +23102,20 @@ } ], "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✔ search jobs with connect manager", + "name": "✔ search job candidates with connect manager", "request": { "method": "GET", "header": [ @@ -17720,22 +23126,22 @@ } ], "url": { - "raw": "{{URL}}/jobs", + "raw": "{{URL}}/jobCandidates", "host": [ "{{URL}}" ], "path": [ - "jobs" + "jobCandidates" ], "query": [ { "key": "page", - "value": "0", + "value": "1", "disabled": true }, { "key": "perPage", - "value": "3", + "value": "1", "disabled": true }, { @@ -17749,53 +23155,18 @@ "disabled": true }, { - "key": "projectId", - "value": "21", - "disabled": true - }, - { - "key": "externalId", - "value": "1212", - "disabled": true - }, - { - "key": "description", - "value": "Dummy", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "resourceType", - "value": "Dummy Resource Type", - "disabled": true - }, - { - "key": "skill", - "value": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", "disabled": true }, { - "key": "rateType", - "value": "hourly", + "key": "userId", + "value": "fe38eed1-af73-41fd-85a2-ac4da1ff09a3", "disabled": true }, { "key": "status", - "value": "sourcing", - "disabled": true - }, - { - "key": "workload", - "value": "full-time", - "disabled": true - }, - { - "key": "title", - "value": "dummy", + "value": "shortlist", "disabled": true } ] @@ -17804,7 +23175,7 @@ "response": [] }, { - "name": "✔ put job with connect manager", + "name": "✔ put job candidate with connect manager", "request": { "method": "PUT", "header": [ @@ -17816,7 +23187,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"selected\"\r\n}", "options": { "raw": { "language": "json" @@ -17824,20 +23195,20 @@ } }, "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✔ patch job with connect manager", + "name": "✔ patch job candidate with connect manager", "request": { "method": "PATCH", "header": [ @@ -17849,7 +23220,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"status\": \"shortlist\"\r\n}", "options": { "raw": { "language": "json" @@ -17857,20 +23228,20 @@ } }, "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✘ delete job with connect manager", + "name": "✘ delete job candidate with connect manager", "request": { "method": "DELETE", "header": [ @@ -17887,29 +23258,73 @@ "raw": { "language": "json" } - } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Interviews", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_for_connect_manager\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] }, - "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Job Candidates", - "item": [ - { - "name": "Before Test", - "item": [ { "name": "create job candidate", "event": [ @@ -17935,7 +23350,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\"\r\n}", "options": { "raw": { "language": "json" @@ -17953,35 +23368,87 @@ } }, "response": [] + }, + { + "name": "create interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"interview_round_created_for_connect_manager\", response.round)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}", + "requestInterview" + ] + } + }, + "response": [] } ] }, { - "name": "✘ create job candidate with connect manager", + "name": "✘ request interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"job_candidate_id_created_by_connect_manager\",data.id);" + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" ], "type": "text/javascript" } } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"30-min-interview\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -17989,148 +23456,89 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}", + "requestInterview" ] } }, "response": [] }, { - "name": "✔ get job candidate with connect manager", - "request": { - "method": "GET", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "name": "✘ get interview with connect manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" } - ], - "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" - ] } - }, - "response": [] - }, - { - "name": "✔ search job candidates with connect manager", + ], "request": { "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/interviews/{{interview_round_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "1", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "asc", - "disabled": true - }, - { - "key": "jobId", - "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", - "disabled": true - }, - { - "key": "userId", - "value": "fe38eed1-af73-41fd-85a2-ac4da1ff09a3", - "disabled": true - }, - { - "key": "status", - "value": "shortlist", - "disabled": true - } + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}", + "interviews", + "{{interview_round_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✔ put job candidate with connect manager", - "request": { - "method": "PUT", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"selected\"\r\n}", - "options": { - "raw": { - "language": "json" - } + "name": "✘ update interview with connect manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" - ] } - }, - "response": [] - }, - { - "name": "✔ patch job candidate with connect manager", + ], "request": { "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"shortlist\"\r\n}", + "raw": "{\r\n \"customMessage\": \"updated\"\r\n}", "options": { "raw": { "language": "json" @@ -18138,46 +23546,55 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/updateInterview/{{interview_round_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" + "{{job_candidate_id_created_for_connect_manager}}", + "updateInterview", + "{{interview_round_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✘ delete job candidate with connect manager", + "name": "✘ search interviews with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/interviews", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" + "{{job_candidate_id_created_for_connect_manager}}", + "interviews" ] } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index af8c680a..e351866c 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -12,6 +12,7 @@ servers: tags: - name: Jobs - name: JobCandidates + - name: Interviews - name: ResourceBookings - name: Teams - name: WorkPeriods @@ -605,7 +606,7 @@ paths: schema: type: array items: - $ref: "#/components/schemas/JobCandidate" + $ref: "#/components/schemas/JobCandidateInterviewsIncluded" headers: X-Next-Page: @@ -690,7 +691,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/JobCandidate" + $ref: "#/components/schemas/JobCandidateInterviewsIncluded" "400": description: Bad request content: @@ -890,6 +891,306 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/requestInterview: + patch: + tags: + - Interviews + description: | + Request a new interview. + + **Authorization** Topcoder token with create interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RequestInterviewBody" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/updateInterview/{round}: + patch: + tags: + - Interviews + description: | + Partially update interview. + + **Authorization** Topcoder token with update interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + - in: path + name: round + description: The interview round. + required: true + schema: + type: integer + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateInterviewRequestBody" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/interviews: + get: + tags: + - Interviews + description: | + Search interviews. + + **Authorization** Topcoder token with read interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + - in: query + name: page + required: false + schema: + type: integer + default: 1 + description: The page number. + - in: query + name: perPage + required: false + schema: + type: integer + default: 20 + description: The number of items to list per page. + - in: query + name: sortBy + required: false + schema: + type: string + default: createdAt + enum: ["round", "createdAt", "updatedAt"] + description: The sort by column. + - in: query + name: sortOrder + required: false + schema: + type: string + default: desc + enum: ["desc", "asc"] + - in: query + name: createdAt + required: false + schema: + type: string + format: date-time + description: The creation date/time of interview. + - in: query + name: updatedAt + required: false + schema: + type: string + format: date-time + description: The last update date/time of interview. + - in: query + name: status + required: false + schema: + type: string + enum: ["Requested"] + description: The interview status. + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/interviews/{round}: + get: + tags: + - Interviews + description: | + Get interview by round. + + **Authorization** Topcoder token with read interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + - in: path + name: round + description: The interview round. + required: true + schema: + type: integer + - in: query + name: fromDb + description: get data from db or not. + required: false + schema: + type: boolean + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" /resourceBookings: post: tags: @@ -3002,6 +3303,67 @@ components: type: string example: "topcoder user" description: "The user who updated the job last time.(Will get the user info from the token)" + JobCandidateInterviewsIncluded: + required: + - id + - jobId + - userId + - status + properties: + id: + type: string + format: uuid + description: "The job id." + jobId: + type: string + format: uuid + description: "The project id." + userId: + type: string + format: uuid + example: "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a" + description: "The user id." + status: + type: string + enum: + [ + "open", + "selected", + "shortlist", + "rejected", + "cancelled", + "interview", + ] + description: "The job candidate status." + externalId: + type: string + example: "1212" + description: "The external id." + resume: + type: string + example: "http://example.com" + description: "The resume link" + interviews: + type: array + description: "Interviews associated to this job candidate." + items: + $ref: "#/components/schemas/Interview" + createdAt: + type: string + format: date-time + description: "The job created date." + createdBy: + type: string + example: "topocder user" + description: "The user who created the job.(Will get the user info from the token)" + updatedAt: + type: string + format: date-time + description: "The job last updated at." + updatedBy: + type: string + example: "topcoder user" + description: "The user who updated the job last time.(Will get the user info from the token)" JobCandidateRequestBody: required: - jobId @@ -3042,6 +3404,125 @@ components: type: string example: "http://example.com" description: "The resume link" + Interview: + required: + - id + - jobCandidateId + - xaiTemplate + - round + - status + - createdAt + - createdBy + properties: + id: + type: string + format: uuid + description: "The interview id." + jobCandidateId: + type: string + format: uuid + description: "The job candidate id." + googleCalendarId: + type: string + example: "dummyId" + description: "The google calendar id." + xaiTemplate: + type: string + example: "30-min-interview" + enum: ["30-min-interview", "60-min-interview"] + description: "The x.ai template name" + customMessage: + type: string + example: "This is a custom message" + description: "The custom message." + round: + type: integer + example: 1 + description: "The interview round." + attendeesList: + type: array + description: "Attendee list for this interview." + items: + type: string + format: email + startTimestamp: + type: string + format: date-time + description: "Interview start time." + status: + type: string + enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + description: "The interview status." + createdAt: + type: string + format: date-time + description: "The interview created date." + createdBy: + type: string + format: uuid + description: "The user who created the interview.(Will get the user info from the token)" + updatedAt: + type: string + format: date-time + description: "The interview last updated at." + updatedBy: + type: string + format: uuid + description: "The user who updated the interview last time.(Will get the user info from the token)" + RequestInterviewBody: + required: + - xaiTemplate + properties: + googleCalendarId: + type: string + example: "dummyId" + description: "The google calendar id." + customMessage: + type: string + example: "This is a custom message" + description: "The custom message." + xaiTemplate: + type: string + enum: ["30-min-interview", "60-min-interview"] + example: "30-min-interview" + description: "The x.ai template name" + attendeesList: + type: array + items: + type: string + format: email + status: + type: string + enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + default: "Scheduling" + description: "The interview status." + UpdateInterviewRequestBody: + properties: + googleCalendarId: + type: string + example: "dummyId" + description: "The google calendar id." + customMessage: + type: string + example: "This is a custom message" + description: "The custom message." + xaiTemplate: + type: string + enum: ["30-min-interview", "60-min-interview"] + example: "30-min-interview" + description: "The x.ai template name" + attendeesList: + type: array + items: + type: string + format: email + startTimestamp: + type: string + format: date-time + status: + type: string + enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + description: "The interview status." JobPatchRequestBody: properties: status: diff --git a/docs/topcoder-bookings.postman_environment.json b/docs/topcoder-bookings.postman_environment.json index fc326e86..58304b6d 100644 --- a/docs/topcoder-bookings.postman_environment.json +++ b/docs/topcoder-bookings.postman_environment.json @@ -1,5 +1,5 @@ { - "id": "8df2004f-35bd-439c-93b2-0d999d88ec99", + "id": "cf10e077-1975-444a-b2d2-3e8e71080526", "name": "topcoder-bookings", "values": [ { @@ -341,9 +341,89 @@ "key": "workPeriodPaymentId_created_for_connect_manager", "value": "", "enabled": true + }, + { + "key": "interviewRound", + "value": "1", + "enabled": true + }, + { + "key": "interview_round_created_by_administrator", + "value": "1", + "enabled": true + }, + { + "key": "job_id_created_for_member", + "value": "", + "enabled": true + }, + { + "key": "job_candidate_id_created_for_member", + "value": "", + "enabled": true + }, + { + "key": "interview_round_created_for_member", + "value": "1", + "enabled": true + }, + { + "key": "job_id_created_for_connect_manager", + "value": "", + "enabled": true + }, + { + "key": "job_candidate_id_created_for_connect_manager", + "value": "", + "enabled": true + }, + { + "key": "interview_round_created_for_connect_manager", + "value": "1", + "enabled": true + }, + { + "key": "completedInterviewJobCandidateId", + "value": "", + "enabled": true + }, + { + "key": "completedInterviewRound", + "value": "", + "enabled": true + }, + { + "key": "token_m2m_create_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJjcmVhdGU6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.VD5j8qdgK3ZPctqD-Nb5KKfSeFIuyajc7Q-wQ_kabIk", + "enabled": true + }, + { + "key": "token_m2m_read_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtaW50ZXJ2aWV3cyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.3Gf42TvkegVi9uiIro75G8-2MqkLdeSbuswVRuZf7t4", + "enabled": true + }, + { + "key": "token_m2m_all_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJhbGw6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.N79nfsZvGzX01hufnMzGG7wNCBqL8eceSpJnHS0lhqo", + "enabled": true + }, + { + "key": "token_m2m_update_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJ1cGRhdGU6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.qGPZrHL9ybzQEq_KlOMM6VfIPJttTVGa7KpVLNDdMHI", + "enabled": true + }, + { + "key": "token_m2m_read_jobCandidate_read_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtam9iQ2FuZGlkYXRlcyByZWFkOnRhYXMtaW50ZXJ2aWV3cyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9._HP8XEoY8eLQRK7K0jgqVPvTGrMS6OwutDU-nCPdopE", + "enabled": true + }, + { + "key": "token_m2m_read_jobCandidates_all_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtam9iQ2FuZGlkYXRlcyBhbGw6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.XQj74JSHp98XKxa1eZnMMpHxGpHeZAHVhLvFAN7gHBY", + "enabled": true } ], "_postman_variable_scope": "environment", - "_postman_exported_at": "2021-04-09T20:23:10.418Z", - "_postman_exported_using": "Postman/8.2.1" + "_postman_exported_at": "2021-04-22T11:06:21.725Z", + "_postman_exported_using": "Postman/8.2.3" } \ No newline at end of file diff --git a/local/kafka-client/topics.txt b/local/kafka-client/topics.txt index dc37db59..8766a1b5 100644 --- a/local/kafka-client/topics.txt +++ b/local/kafka-client/topics.txt @@ -13,4 +13,7 @@ taas.jobcandidate.delete taas.resourcebooking.delete taas.workperiod.delete taas.workperiodpayment.delete +taas.interview.requested +taas.interview.update +taas.interview.bulkUpdate external.action.email diff --git a/migrations/2021-04-12-create-interviews-table.js b/migrations/2021-04-12-create-interviews-table.js new file mode 100644 index 00000000..53eaab1a --- /dev/null +++ b/migrations/2021-04-12-create-interviews-table.js @@ -0,0 +1,102 @@ +'use strict'; + +const config = require('config') +const _ = require('lodash') +const { Interviews } = require('../app-constants') + +// allowed status values +const statuses = _.values(Interviews.Status) + +/** + * Create `interviews` table & relations. + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const table = { schema: config.DB_SCHEMA_NAME, tableName: 'interviews' } + await queryInterface.createTable(table, { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4 + }, + jobCandidateId: { + field: 'job_candidate_id', + type: Sequelize.UUID, + allowNull: false, + references: { + model: { + tableName: 'job_candidates', + schema: config.DB_SCHEMA_NAME + }, + key: 'id' + } + }, + googleCalendarId: { + field: 'google_calendar_id', + type: Sequelize.STRING(255) + }, + customMessage: { + field: 'custom_message', + type: Sequelize.TEXT + }, + xaiTemplate: { + field: 'xai_template', + type: Sequelize.STRING(255), + allowNull: false + }, + round: { + type: Sequelize.INTEGER, + allowNull: false + }, + startTimestamp: { + field: 'start_timestamp', + type: Sequelize.DATE + }, + attendeesList: { + field: 'attendees_list', + type: Sequelize.ARRAY(Sequelize.STRING) + }, + status: { + type: Sequelize.ENUM(statuses), + allowNull: false + }, + createdBy: { + field: 'created_by', + type: Sequelize.UUID, + allowNull: false + }, + updatedBy: { + field: 'updated_by', + type: Sequelize.UUID + }, + createdAt: { + field: 'created_at', + type: Sequelize.DATE + }, + updatedAt: { + field: 'updated_at', + type: Sequelize.DATE + }, + deletedAt: { + field: 'deleted_at', + type: Sequelize.DATE + } + }, { schema: config.DB_SCHEMA_NAME }) + }, + + down: async (queryInterface, Sequelize) => { + const table = { schema: config.DB_SCHEMA_NAME, tableName: 'interviews' } + const statusTypeName = `${table.schema}.enum_${table.tableName}_status` + const transaction = await queryInterface.sequelize.transaction() + try { + await queryInterface.dropTable(table, { transaction }) + // drop enum type for status column + await queryInterface.sequelize.query(`DROP TYPE ${statusTypeName}`, { transaction }) + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +}; diff --git a/package-lock.json b/package-lock.json index 50293037..76b17135 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1500,6 +1500,15 @@ "write-file-atomic": "^3.0.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1891,6 +1900,15 @@ "vary": "^1" } }, + "cron-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.3.0.tgz", + "integrity": "sha512-Tz5WxSrDVhR7YVuLuUxhXoMGHCWoe8I7g8APkyRZNaINXHQ3zcfK97av6hBYy9ue4sOLI7ZH7SeQqi/t4jR+5A==", + "requires": { + "is-nan": "^1.3.0", + "luxon": "^1.25.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3098,6 +3116,16 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -3201,25 +3229,6 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3693,6 +3702,15 @@ "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", "dev": true }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, "is-negative-zero": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", @@ -4567,6 +4585,11 @@ } } }, + "long-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4609,6 +4632,11 @@ "es5-ext": "~0.10.2" } }, + "luxon": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz", + "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==" + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -4963,11 +4991,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", @@ -5018,6 +5041,16 @@ "process-on-spawn": "^1.0.0" } }, + "node-schedule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.0.0.tgz", + "integrity": "sha512-cHc9KEcfiuXxYDU+HjsBVo2FkWL1jRAUoczFoMIzRBpOA4p/NRHuuLs85AWOLgKsHtSPjN8csvwIxc2SqMv+CQ==", + "requires": { + "cron-parser": "^3.1.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.3.0" + } + }, "nodemon": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", @@ -6773,6 +6806,11 @@ } } }, + "sorted-array-functions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", + "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==" + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7411,12 +7449,6 @@ "is-typedarray": "^1.0.0" } }, - "uglify-js": { - "version": "3.12.8", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz", - "integrity": "sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w==", - "optional": true - }, "umzug": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", @@ -7814,11 +7846,6 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, "workerpool": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", diff --git a/package.json b/package.json index 0168b120..d3249fcc 100644 --- a/package.json +++ b/package.json @@ -45,11 +45,11 @@ "express": "^4.17.1", "express-interceptor": "^1.2.0", "get-parameter-names": "^0.3.0", - "handlebars": "^4.7.6", "http-status": "^1.4.2", "http-status-codes": "^2.1.4", "joi": "^17.2.1", "lodash": "^4.17.20", + "node-schedule": "^2.0.0", "moment-timezone": "^0.5.33", "pg": "^8.4.0", "pg-hstore": "^2.3.3", diff --git a/scripts/data/exportData.js b/scripts/data/exportData.js index 30529aa7..356fcfc6 100644 --- a/scripts/data/exportData.js +++ b/scripts/data/exportData.js @@ -2,12 +2,29 @@ * Export data to a json file */ const config = require('config') +const { Interview, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + +const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: are you sure you want to export all data in the database to a json file with the path ${filePath}? This will overwrite the file.` -const dataModels = ['Job', 'JobCandidate', 'ResourceBooking', 'WorkPeriod', 'WorkPeriodPayment'] +const dataModels = ['Job', jobCandidateModelOpts, 'ResourceBooking', workPeriodModelOpts] async function exportData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/data/importData.js b/scripts/data/importData.js index e4daa58d..52b3feb8 100644 --- a/scripts/data/importData.js +++ b/scripts/data/importData.js @@ -2,12 +2,29 @@ * Import data from a json file into the db and index it in Elasticsearch */ const config = require('config') +const { Interview, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + +const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: this would remove existing data. Are you sure you want to import data from a json file with the path ${filePath}?` -const dataModels = ['Job', 'JobCandidate', 'ResourceBooking', 'WorkPeriod', 'WorkPeriodPayment'] +const dataModels = ['Job', jobCandidateModelOpts, 'ResourceBooking', workPeriodModelOpts] async function importData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/es/reIndexAll.js b/scripts/es/reIndexAll.js index 215efaa2..6a7bdf3f 100644 --- a/scripts/es/reIndexAll.js +++ b/scripts/es/reIndexAll.js @@ -2,18 +2,35 @@ * Reindex all data in Elasticsearch using data from database */ const config = require('config') +const { Interview, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') const userPrompt = 'WARNING: this would remove existent data! Are you sure want to reindex all indices?' +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + +const workPeriodModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + async function indexAll () { await helper.promptUser(userPrompt, async () => { try { await helper.indexBulkDataToES('Job', config.get('esConfig.ES_INDEX_JOB'), logger) - await helper.indexBulkDataToES('JobCandidate', config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) + await helper.indexBulkDataToES(jobCandidateModelOpts, config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) await helper.indexBulkDataToES('ResourceBooking', config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) - await helper.indexBulkDataToES('WorkPeriod', config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) + await helper.indexBulkDataToES(workPeriodModelOpts, config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'indexAll' }) diff --git a/scripts/es/reIndexJobCandidates.js b/scripts/es/reIndexJobCandidates.js index 7e0aec22..585416a5 100644 --- a/scripts/es/reIndexJobCandidates.js +++ b/scripts/es/reIndexJobCandidates.js @@ -2,6 +2,7 @@ * Reindex JobCandidates data in Elasticsearch using data from database */ const config = require('config') +const { Interview } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -10,11 +11,19 @@ const index = config.get('esConfig.ES_INDEX_JOB_CANDIDATE') const reIndexAllJobCandidatesPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the index ${index}?` const reIndexJobCandidatePrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the document with id ${jobCandidateId} in index ${index}?` +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + async function reIndexJobCandidates () { if (jobCandidateId === null) { await helper.promptUser(reIndexAllJobCandidatesPrompt, async () => { try { - await helper.indexBulkDataToES('JobCandidate', index, logger) + await helper.indexBulkDataToES(jobCandidateModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexJobCandidates' }) @@ -24,7 +33,7 @@ async function reIndexJobCandidates () { } else { await helper.promptUser(reIndexJobCandidatePrompt, async () => { try { - await helper.indexDataToEsById(jobCandidateId, 'JobCandidate', index, logger) + await helper.indexDataToEsById(jobCandidateId, jobCandidateModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexJobCandidates' }) diff --git a/scripts/es/reIndexWorkPeriods.js b/scripts/es/reIndexWorkPeriods.js index a759d6c1..a6f30737 100644 --- a/scripts/es/reIndexWorkPeriods.js +++ b/scripts/es/reIndexWorkPeriods.js @@ -2,6 +2,7 @@ * Reindex WorkPeriods data in Elasticsearch using data from database */ const config = require('config') +const { WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -10,11 +11,19 @@ const index = config.get('esConfig.ES_INDEX_WORK_PERIOD') const reIndexAllWorkPeriodsPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the index ${index}` const reIndexWorkPeriodPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the document with id ${workPeriodId} in index ${index}?` +const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + async function reIndexWorkPeriods () { if (workPeriodId === null) { await helper.promptUser(reIndexAllWorkPeriodsPrompt, async () => { try { - await helper.indexBulkDataToES('WorkPeriod', index, logger) + await helper.indexBulkDataToES(workPeriodModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexWorkPeriods' }) @@ -24,7 +33,7 @@ async function reIndexWorkPeriods () { } else { await helper.promptUser(reIndexWorkPeriodPrompt, async () => { try { - await helper.indexDataToEsById(workPeriodId, 'WorkPeriod', index, logger) + await helper.indexDataToEsById(workPeriodId, workPeriodModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexWorkPeriods' }) diff --git a/src/bootstrap.js b/src/bootstrap.js index bc5b0b47..19e93973 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -1,10 +1,15 @@ const fs = require('fs') const Joi = require('joi') const path = require('path') +const _ = require('lodash') +const { Interviews } = require('../app-constants') const logger = require('./common/logger') const constants = require('../app-constants') const config = require('config') +const allowedInterviewStatuses = _.values(Interviews.Status) +const allowedXAITemplate = _.values(Interviews.XaiTemplate) + Joi.page = () => Joi.number().integer().min(1).default(1) Joi.perPage = () => Joi.number().integer().min(1).default(20) Joi.rateType = () => Joi.string().valid('hourly', 'daily', 'weekly', 'monthly') @@ -14,6 +19,8 @@ Joi.workload = () => Joi.string().valid('full-time', 'fractional') Joi.jobCandidateStatus = () => Joi.string().valid('open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview', 'topcoder-rejected') Joi.title = () => Joi.string().max(128) Joi.paymentStatus = () => Joi.string().valid('pending', 'partially-completed', 'completed', 'cancelled') +Joi.xaiTemplate = () => Joi.string().valid(...allowedXAITemplate) +Joi.interviewStatus = () => Joi.string().valid(...allowedInterviewStatuses) Joi.workPeriodPaymentStatus = () => Joi.string().valid('completed', 'cancelled') // Empty string is not allowed by Joi by default and must be enabled with allow(''). // See https://joi.dev/api/?v=17.3.0#string fro details why it's like this. diff --git a/src/common/helper.js b/src/common/helper.js index 00353bed..686d1d82 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -12,6 +12,7 @@ const HttpStatus = require('http-status-codes') const _ = require('lodash') const request = require('superagent') const elasticsearch = require('@elastic/elasticsearch') +const { ResponseError: ESResponseError } = require('@elastic/elasticsearch/lib/errors') const errors = require('../common/errors') const logger = require('./logger') const models = require('../models') @@ -83,6 +84,24 @@ esIndexPropertyMapping[config.get('esConfig.ES_INDEX_JOB_CANDIDATE')] = { status: { type: 'keyword' }, externalId: { type: 'keyword' }, resume: { type: 'text' }, + interviews: { + type: 'nested', + properties: { + id: { type: 'keyword' }, + jobCandidateId: { type: 'keyword' }, + googleCalendarId: { type: 'keyword' }, + customMessage: { type: 'text' }, + xaiTemplate: { type: 'keyword' }, + startTimestamp: { type: 'date' }, + attendeesList: [], + round: { type: 'integer' }, + status: { type: 'keyword' }, + createdAt: { type: 'date' }, + createdBy: { type: 'keyword' }, + updatedAt: { type: 'date' }, + updatedBy: { type: 'keyword' } + } + }, createdAt: { type: 'date' }, createdBy: { type: 'keyword' }, updatedAt: { type: 'date' }, @@ -246,11 +265,14 @@ function getBulksFromDocuments (data) { /** * Index records in bulk -* @param {Object} modelName the model name in db +* @param {Object | String} modelOpts the model name in db, or model options * @param {Object} indexName the index name * @param {Object} logger the logger object */ -async function indexBulkDataToES (modelName, indexName, logger) { +async function indexBulkDataToES (modelOpts, indexName, logger) { + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + logger.info({ component: 'indexBulkDataToES', message: `Reindexing of ${modelName}s started!` }) const esClient = getESClient() @@ -265,23 +287,13 @@ async function indexBulkDataToES (modelName, indexName, logger) { // get data from db logger.info({ component: 'indexBulkDataToES', message: 'Getting data from database' }) const model = models[modelName] - const criteria = { - raw: true - } - if (modelName === 'WorkPeriod') { - criteria.raw = false - criteria.include = [{ - model: models.WorkPeriodPayment, - as: 'payments', - required: false - }] - } - const data = await model.findAll(criteria) - if (_.isEmpty(data)) { + const data = await model.findAll({ include }) + const rawObjects = _.map(data, r => r.toJSON()) + if (_.isEmpty(rawObjects)) { logger.info({ component: 'indexBulkDataToES', message: `No data in database for ${modelName}` }) return } - const bulks = getBulksFromDocuments(data) + const bulks = getBulksFromDocuments(rawObjects) const startTime = Date.now() let doneCount = 0 @@ -305,19 +317,22 @@ async function indexBulkDataToES (modelName, indexName, logger) { /** * Index job by id - * @param {Object} modelName the model name in db + * @param {Object | String} modelOpts the model name in db, or model options * @param {Object} indexName the index name * @param {string} id the job id * @param {Object} logger the logger object */ -async function indexDataToEsById (id, modelName, indexName, logger) { +async function indexDataToEsById (id, modelOpts, indexName, logger) { + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + logger.info({ component: 'indexDataToEsById', message: `Reindexing of ${modelName} with id ${id} started!` }) const esClient = getESClient() logger.info({ component: 'indexDataToEsById', message: 'Getting data from database' }) const model = models[modelName] - const data = await model.findById(id, modelName === 'WorkPeriod') + const data = await model.findById(id, include) logger.info({ component: 'indexDataToEsById', message: 'Indexing data into Elasticsearch' }) await esClient.index({ index: indexName, @@ -351,7 +366,10 @@ async function importData (pathToFile, dataModels, logger) { const jsonData = JSON.parse(fs.readFileSync(pathToFile).toString()) for (let index = 0; index < dataModels.length; index += 1) { - const modelName = dataModels[index] + const modelOpts = dataModels[index] + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + currentModelName = modelName const model = models[modelName] const modelRecords = jsonData[modelName] @@ -359,7 +377,7 @@ async function importData (pathToFile, dataModels, logger) { if (modelRecords && modelRecords.length > 0) { logger.info({ component: 'importData', message: `Importing data for model: ${modelName}` }) - await model.bulkCreate(modelRecords, { transaction }) + await model.bulkCreate(modelRecords, { include, transaction }) logger.info({ component: 'importData', message: `Records imported for model: ${modelName} = ${modelRecords.length}` }) } else { logger.info({ component: 'importData', message: `No records to import for model: ${modelName}` }) @@ -392,10 +410,24 @@ async function importData (pathToFile, dataModels, logger) { } // after importing, index data + const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: models.Interview, + as: 'interviews' + }] + } + const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: models.WorkPeriodPayment, + as: 'payments' + }] + } await indexBulkDataToES('Job', config.get('esConfig.ES_INDEX_JOB'), logger) - await indexBulkDataToES('JobCandidate', config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) + await indexBulkDataToES(jobCandidateModelOpts, config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) await indexBulkDataToES('ResourceBooking', config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) - await indexBulkDataToES('WorkPeriod', config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) + await indexBulkDataToES(workPeriodModelOpts, config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) } /** @@ -409,12 +441,13 @@ async function exportData (pathToFile, dataModels, logger) { const allModelsRecords = {} for (let index = 0; index < dataModels.length; index += 1) { - const modelName = dataModels[index] - const modelRecords = await models[modelName].findAll({ - raw: true - }) - allModelsRecords[modelName] = modelRecords - logger.info({ component: 'exportData', message: `Records loaded for model: ${modelName} = ${modelRecords.length}` }) + const modelOpts = dataModels[index] + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + const modelRecords = await models[modelName].findAll({ include }) + const rawRecords = _.map(modelRecords, r => r.toJSON()) + allModelsRecords[modelName] = rawRecords + logger.info({ component: 'exportData', message: `Records loaded for model: ${modelName} = ${rawRecords.length}` }) } fs.writeFileSync(pathToFile, JSON.stringify(allModelsRecords)) @@ -702,7 +735,7 @@ async function postEvent (topic, payload, options = {}) { * @returns {Boolean} the result */ function isDocumentMissingException (err) { - if (err.statusCode === 404) { + if (err.statusCode === 404 && err instanceof ESResponseError) { return true } return false @@ -780,6 +813,8 @@ async function getUserById (userId, enrich) { if (enrich) { user.skills = (res.body.skills || []).map((skillObj) => _.pick(skillObj.skill, ['id', 'name'])) + const attributes = _.get(res, 'body.attributes', []) + user.attributes = _.map(attributes, attr => _.pick(attr, ['id', 'value', 'attribute.id', 'attribute.name'])) } return user @@ -1178,6 +1213,18 @@ async function deleteProjectMember (currentUser, projectId, projectMemberId) { } } +/** + * Gets requested attribute value from user's attributes array. + * @param {Object} user The enriched (i.e. includes attributes) user object from users API. (check getUserById, getUserByExternalId functions) + * @param {String} attributeName Requested attribute name, e.g. "email" + * @returns attribute value + */ +function getUserAttributeValue (user, attributeName) { + const attributes = _.get(user, 'attributes', []) + const targetAttribute = _.find(attributes, a => a.attribute.name === attributeName) + return _.get(targetAttribute, 'value') +} + /** * Create a new challenge * @@ -1342,6 +1389,7 @@ module.exports = { listProjectMembers, listProjectMemberInvites, deleteProjectMember, + getUserAttributeValue, createChallenge, updateChallenge, createChallengeResource, diff --git a/src/controllers/InterviewController.js b/src/controllers/InterviewController.js new file mode 100644 index 00000000..d9ae8e44 --- /dev/null +++ b/src/controllers/InterviewController.js @@ -0,0 +1,52 @@ +/** + * Controller for Interview endpoints + */ +const service = require('../services/InterviewService') +const helper = require('../common/helper') + +/** + * Get interview by round + * @param req the request + * @param res the response + */ +async function getInterviewByRound (req, res) { + const { jobCandidateId, round } = req.params + res.send(await service.getInterviewByRound(req.authUser, jobCandidateId, round, req.query.fromDb)) +} + +/** + * Request interview + * @param req the request + * @param res the response + */ +async function requestInterview (req, res) { + res.send(await service.requestInterview(req.authUser, req.params.jobCandidateId, req.body)) +} + +/** + * Patch (partially update) interview + * @param req the request + * @param res the response + */ +async function partiallyUpdateInterview (req, res) { + const { jobCandidateId, round } = req.params + res.send(await service.partiallyUpdateInterview(req.authUser, jobCandidateId, round, req.body)) +} + +/** + * Search interviews + * @param req the request + * @param res the response + */ +async function searchInterviews (req, res) { + const result = await service.searchInterviews(req.authUser, req.params.jobCandidateId, req.query) + helper.setResHeaders(req, res, result) + res.send(result.result) +} + +module.exports = { + getInterviewByRound, + requestInterview, + partiallyUpdateInterview, + searchInterviews +} diff --git a/src/eventHandlers/InterviewEventHandler.js b/src/eventHandlers/InterviewEventHandler.js new file mode 100644 index 00000000..ee503ee5 --- /dev/null +++ b/src/eventHandlers/InterviewEventHandler.js @@ -0,0 +1,62 @@ +/* + * Handle events for Interview. + */ + +const models = require('../models') +const logger = require('../common/logger') +const helper = require('../common/helper') +const teamService = require('../services/TeamService') + +/** + * Once we request Interview for a JobCandidate, the invitation emails to be sent out. + * + * @param {Object} payload the event payload + * @returns {undefined} + */ +async function sendInvitationEmail (payload) { + const interview = payload.value + // get job candidate user details + const jobCandidate = await models.JobCandidate.findById(interview.jobCandidateId) + const jobCandidateUser = await helper.getUserById(jobCandidate.userId, true) + const jobCandidateUserEmail = helper.getUserAttributeValue(jobCandidateUser, 'email') + // get customer details + const job = await jobCandidate.getJob() + const customerUser = await helper.getUserByExternalId(job.externalId, true) + const customerUserEmail = helper.getUserAttributeValue(customerUser, 'email') + if (jobCandidateUserEmail && customerUserEmail) { + teamService.sendEmail({}, { + template: 'interview-invitation', + recipients: [jobCandidateUserEmail, customerUserEmail], + cc: interview.attendeesList, + data: { + interviewType: interview.xaiTemplate, + jobName: job.title, + candidateName: `${jobCandidateUser.firstName} ${jobCandidateUser.lastName}`, + customMessage: interview.customMessage + } + }) + } else { + // one (or both) of the emails are missing due to some reason + // for e.g. some users' externalIds may be set to null or similar + // log error + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInvitationEmail', + message: 'Couldn\'t sent invitation emails. Insufficient details.' + }) + } +} + +/** + * Process interview request event. + * + * @param {Object} payload the event payload + * @returns {undefined} + */ +async function processRequest (payload) { + await sendInvitationEmail(payload) +} + +module.exports = { + processRequest +} diff --git a/src/eventHandlers/index.js b/src/eventHandlers/index.js index 309b5f82..17445994 100644 --- a/src/eventHandlers/index.js +++ b/src/eventHandlers/index.js @@ -7,6 +7,7 @@ const eventDispatcher = require('../common/eventDispatcher') const JobEventHandler = require('./JobEventHandler') const JobCandidateEventHandler = require('./JobCandidateEventHandler') const ResourceBookingEventHandler = require('./ResourceBookingEventHandler') +const InterviewEventHandler = require('./InterviewEventHandler') const logger = require('../common/logger') const TopicOperationMapping = { @@ -14,7 +15,8 @@ const TopicOperationMapping = { [config.TAAS_JOB_CANDIDATE_CREATE_TOPIC]: JobCandidateEventHandler.processCreate, [config.TAAS_RESOURCE_BOOKING_CREATE_TOPIC]: ResourceBookingEventHandler.processCreate, [config.TAAS_RESOURCE_BOOKING_UPDATE_TOPIC]: ResourceBookingEventHandler.processUpdate, - [config.TAAS_RESOURCE_BOOKING_DELETE_TOPIC]: ResourceBookingEventHandler.processDelete + [config.TAAS_RESOURCE_BOOKING_DELETE_TOPIC]: ResourceBookingEventHandler.processDelete, + [config.TAAS_INTERVIEW_REQUEST_TOPIC]: InterviewEventHandler.processRequest } /** diff --git a/src/models/Interview.js b/src/models/Interview.js new file mode 100644 index 00000000..424251a3 --- /dev/null +++ b/src/models/Interview.js @@ -0,0 +1,124 @@ +const { Sequelize, Model } = require('sequelize') +const config = require('config') +const _ = require('lodash') +const { Interviews } = require('../../app-constants') +const errors = require('../common/errors') + +// allowed status values +const statuses = _.values(Interviews.Status) + +module.exports = (sequelize) => { + class Interview extends Model { + /** + * Create association between models + * @param {Object} models the database models + */ + static associate (models) { + Interview.belongsTo(models.JobCandidate, { foreignKey: 'jobCandidateId' }) + } + + /** + * Get interview by id + * @param {String} id the interview id + * @returns {Interview} the Interview instance + */ + static async findById (id) { + const interview = await Interview.findOne({ + where: { + id + } + }) + if (!interview) { + throw new errors.NotFoundError(`id: ${id} "Interview" doesn't exist.`) + } + return interview + } + } + Interview.init( + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4 + }, + jobCandidateId: { + field: 'job_candidate_id', + type: Sequelize.UUID, + allowNull: false + }, + googleCalendarId: { + field: 'google_calendar_id', + type: Sequelize.STRING(255) + }, + customMessage: { + field: 'custom_message', + type: Sequelize.TEXT + }, + xaiTemplate: { + field: 'xai_template', + type: Sequelize.STRING(255), + allowNull: false + }, + round: { + type: Sequelize.INTEGER, + allowNull: false + }, + startTimestamp: { + field: 'start_timestamp', + type: Sequelize.DATE + }, + attendeesList: { + field: 'attendees_list', + type: Sequelize.ARRAY(Sequelize.STRING) + }, + status: { + type: Sequelize.ENUM(statuses), + allowNull: false + }, + createdBy: { + field: 'created_by', + type: Sequelize.UUID, + allowNull: false + }, + updatedBy: { + field: 'updated_by', + type: Sequelize.UUID + }, + createdAt: { + field: 'created_at', + type: Sequelize.DATE + }, + updatedAt: { + field: 'updated_at', + type: Sequelize.DATE + }, + deletedAt: { + field: 'deleted_at', + type: Sequelize.DATE + } + }, + { + schema: config.DB_SCHEMA_NAME, + sequelize, + tableName: 'interviews', + paranoid: true, + deletedAt: 'deletedAt', + createdAt: 'createdAt', + updatedAt: 'updatedAt', + timestamps: true, + defaultScope: { + attributes: { + exclude: ['deletedAt'] + } + }, + hooks: { + afterCreate: (interview) => { + delete interview.dataValues.deletedAt + } + } + } + ) + + return Interview +} diff --git a/src/models/JobCandidate.js b/src/models/JobCandidate.js index 00e83991..819b9177 100644 --- a/src/models/JobCandidate.js +++ b/src/models/JobCandidate.js @@ -11,18 +11,21 @@ module.exports = (sequelize) => { static associate (models) { JobCandidate._models = models JobCandidate.belongsTo(models.Job, { foreignKey: 'jobId' }) + JobCandidate.hasMany(models.Interview, { foreignKey: 'jobCandidateId', as: 'interviews' }) } /** * Get job candidate by id * @param {String} id the job candidate id + * @param {Array} include include options * @returns {JobCandidate} the JobCandidate instance */ - static async findById (id) { + static async findById (id, include = []) { const jobCandidate = await JobCandidate.findOne({ where: { id - } + }, + include }) if (!jobCandidate) { throw new errors.NotFoundError(`id: ${id} "JobCandidate" doesn't exists.`) @@ -98,6 +101,13 @@ module.exports = (sequelize) => { hooks: { afterCreate: (jobCandidate) => { delete jobCandidate.dataValues.deletedAt + }, + afterDestroy: async (jobCandidate) => { + // cascade (soft) delete interviews associated with this jobCandidate + const jobCandidateId = jobCandidate.id + await sequelize.models.Interview.destroy({ + where: { jobCandidateId } + }) } } } diff --git a/src/routes/InterviewRoutes.js b/src/routes/InterviewRoutes.js new file mode 100644 index 00000000..e8f8e960 --- /dev/null +++ b/src/routes/InterviewRoutes.js @@ -0,0 +1,39 @@ +/** + * Contains interview routes + */ +const constants = require('../../app-constants') + +module.exports = { + '/jobCandidates/:jobCandidateId/requestInterview': { + patch: { + controller: 'InterviewController', + method: 'requestInterview', + auth: 'jwt', + scopes: [constants.Scopes.CREATE_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + }, + '/jobCandidates/:jobCandidateId/updateInterview/:round': { + patch: { + controller: 'InterviewController', + method: 'partiallyUpdateInterview', + auth: 'jwt', + scopes: [constants.Scopes.UPDATE_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + }, + '/jobCandidates/:jobCandidateId/interviews': { + get: { + controller: 'InterviewController', + method: 'searchInterviews', + auth: 'jwt', + scopes: [constants.Scopes.READ_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + }, + '/jobCandidates/:jobCandidateId/interviews/:round': { + get: { + controller: 'InterviewController', + method: 'getInterviewByRound', + auth: 'jwt', + scopes: [constants.Scopes.READ_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + } +} diff --git a/src/services/InterviewService.js b/src/services/InterviewService.js new file mode 100644 index 00000000..2afad72e --- /dev/null +++ b/src/services/InterviewService.js @@ -0,0 +1,387 @@ +/** + * This service provides operations of Interview. + */ + +const _ = require('lodash') +const Joi = require('joi') +const config = require('config') +const { Op, ForeignKeyConstraintError } = require('sequelize') +const { v4: uuid } = require('uuid') +const { Interviews: InterviewConstants } = require('../../app-constants') +const helper = require('../common/helper') +const logger = require('../common/logger') +const errors = require('../common/errors') +const models = require('../models') + +const Interview = models.Interview +const esClient = helper.getESClient() + +/** + * Ensures user is permitted for the operation. + * + * @param {Object} currentUser the user who perform this operation. + * @throws {errors.ForbiddenError} + */ +function ensureUserIsPermitted (currentUser) { + const isUserPermitted = currentUser.hasManagePermission || currentUser.isMachine + if (isUserPermitted !== true) { + throw new errors.ForbiddenError('You are not allowed to perform this action!') + } +} + +/** + * Handles common sequelize errors + * @param {Object} err error + * @param {String} jobCandidateId the job candidate id + */ +function handleSequelizeError (err, jobCandidateId) { + // jobCandidateId doesn't exist - gracefully handle + if (err instanceof ForeignKeyConstraintError) { + throw new errors.NotFoundError( + `The job candidate with id=${jobCandidateId} doesn't exist.` + ) + } + // another type of sequelize error - extract the details and throw + const errDetail = _.get(err, 'original.detail') + if (errDetail) { + throw new errors.BadRequestError(errDetail) + } +} + +/** + * Get interview by round + * @param {Object} currentUser the user who perform this operation. + * @param {String} jobCandidateId the job candidate id + * @param {Number} round the interview round + * @param {Boolean} fromDb flag if query db for data or not + * @returns {Object} the interview + */ +async function getInterviewByRound (currentUser, jobCandidateId, round, fromDb = false) { + // check permission + ensureUserIsPermitted(currentUser) + if (!fromDb) { + try { + // get job candidate from ES + const jobCandidateES = await esClient.get({ + index: config.esConfig.ES_INDEX_JOB_CANDIDATE, + id: jobCandidateId + }) + // extract interviews from ES object + const jobCandidateInterviews = _.get(jobCandidateES, 'body._source.interviews', []) + // find interview by round + const interview = _.find(jobCandidateInterviews, interview => interview.round === round) + if (interview) { + return interview + } + // if reaches here, the interview with this round is not found + throw new errors.NotFoundError(`Interview doesn't exist with round: ${round}`) + } catch (err) { + if (helper.isDocumentMissingException(err)) { + throw new errors.NotFoundError(`id: ${jobCandidateId} "JobCandidate" not found`) + } + logger.logFullError(err, { component: 'InterviewService', context: 'getInterviewByRound' }) + throw err + } + } + // either ES query failed or `fromDb` is set - fallback to DB + logger.info({ component: 'InterviewService', context: 'getInterview', message: 'try to query db for data' }) + + const interview = await Interview.findOne({ + where: { jobCandidateId, round } + }) + // throw NotFound error if doesn't exist + if (!!interview !== true) { + throw new errors.NotFoundError(`Interview doesn't exist with jobCandidateId: ${jobCandidateId} and round: ${round}`) + } + + return interview.dataValues +} + +getInterviewByRound.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + round: Joi.number().integer().positive().required(), + fromDb: Joi.boolean() +}).required() + +/** + * Request interview + * @param {Object} currentUser the user who perform this operation + * @param {String} jobCandidateId the job candidate id + * @param {Object} interview the interview to be created + * @returns {Object} the created/requested interview + */ +async function requestInterview (currentUser, jobCandidateId, interview) { + // check permission + ensureUserIsPermitted(currentUser) + + interview.id = uuid() + interview.jobCandidateId = jobCandidateId + interview.createdBy = await helper.getUserId(currentUser.userId) + + // find the round count + const round = await Interview.count({ + where: { jobCandidateId } + }) + interview.round = round + 1 + + // create + try { + const created = await Interview.create(interview) + await helper.postEvent(config.TAAS_INTERVIEW_REQUEST_TOPIC, created.toJSON()) + return created.dataValues + } catch (err) { + // gracefully handle if one of the common sequelize errors + handleSequelizeError(err, jobCandidateId) + // if reaches here, it's not one of the common errors handled in `handleSequelizeError` + throw err + } +} + +requestInterview.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + interview: Joi.object().keys({ + googleCalendarId: Joi.string().allow(null), + customMessage: Joi.string().allow(null), + xaiTemplate: Joi.xaiTemplate().required(), + attendeesList: Joi.array().items(Joi.string().email()).allow(null), + status: Joi.interviewStatus().default(InterviewConstants.Status.Scheduling) + }).required() +}).required() + +/** + * Patch (partially update) interview + * @param {Object} currentUser the user who perform this operation + * @param {String} jobCandidateId the job candidate id + * @param {Number} round the interview round + * @param {Object} data object containing patched fields + * @returns {Object} the patched interview object + */ +async function partiallyUpdateInterview (currentUser, jobCandidateId, round, data) { + // check permission + ensureUserIsPermitted(currentUser) + + const interview = await Interview.findOne({ + where: { + jobCandidateId, round + } + }) + // throw NotFound error if doesn't exist + if (!!interview !== true) { + throw new errors.NotFoundError(`Interview doesn't exist with jobCandidateId: ${jobCandidateId} and round: ${round}`) + } + + const oldValue = interview.toJSON() + + // only status can be updated for Completed interviews + if (oldValue.status === InterviewConstants.Status.Completed) { + const updatedFields = _.keys(data) + if (updatedFields.length !== 1 || !_.includes(updatedFields, 'status')) { + throw new errors.BadRequestError('Only the "status" can be updated for Completed interviews.') + } + } + + data.updatedBy = await helper.getUserId(currentUser.userId) + try { + const updated = await interview.update(data) + await helper.postEvent(config.TAAS_INTERVIEW_UPDATE_TOPIC, updated.toJSON(), { oldValue: oldValue }) + return updated.dataValues + } catch (err) { + // gracefully handle if one of the common sequelize errors + handleSequelizeError(err, jobCandidateId) + // if reaches here, it's not one of the common errors handled in `handleSequelizeError` + throw err + } +} + +partiallyUpdateInterview.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + round: Joi.number().integer().positive().required(), + data: Joi.object().keys({ + googleCalendarId: Joi.string().when('status', { + is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], + then: Joi.required(), + otherwise: Joi.allow(null) + }), + customMessage: Joi.string().allow(null), + xaiTemplate: Joi.xaiTemplate(), + startTimestamp: Joi.date().greater('now').when('status', { + is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], + then: Joi.required(), + otherwise: Joi.allow(null) + }), + attendeesList: Joi.array().items(Joi.string().email()).allow(null), + status: Joi.interviewStatus() + }).required().min(1) // at least one key - i.e. don't allow empty object +}).required() + +/** + * List interviews + * @param {Object} currentUser the user who perform this operation. + * @param {String} jobCandidateId the job candidate id + * @param {Object} criteria the search criteria + * @returns {Object} the search result, contain total/page/perPage and result array + */ +async function searchInterviews (currentUser, jobCandidateId, criteria) { + // check permission + ensureUserIsPermitted(currentUser) + + const { page, perPage } = criteria + + try { + // construct query for nested search + const esQueryBody = { + _source: false, + query: { + nested: { + path: 'interviews', + query: { + bool: { + must: [] + } + }, + inner_hits: { + size: 100 // max. inner_hits size + } + } + } + } + // add filtering terms + // jobCandidateId + esQueryBody.query.nested.query.bool.must.push({ + term: { + 'interviews.jobCandidateId': { + value: jobCandidateId + } + } + }) + // criteria + _.each(_.pick(criteria, ['status', 'createdAt', 'updatedAt']), (value, key) => { + const innerKey = `interviews.${key}` + esQueryBody.query.nested.query.bool.must.push({ + term: { + [innerKey]: { + value + } + } + }) + }) + // search + const { body } = await esClient.search({ + index: config.esConfig.ES_INDEX_JOB_CANDIDATE, + body: esQueryBody + }) + // get jobCandidate hit from body - there's always one jobCandidate hit as we search via jobCandidateId + // extract inner interview hits from jobCandidate + const interviewHits = _.get(body, 'hits.hits[0].inner_hits.interviews.hits.hits', []) + const interviews = _.map(interviewHits, '_source') + + // we need to sort & paginate interviews manually + // as it's not possible with ES query on nested type + // (ES applies pagination & sorting on parent documents, not on the nested objects) + + // sort + const sortedInterviews = _.orderBy(interviews, criteria.sortBy, criteria.sortOrder) + // paginate + const start = (page - 1) * perPage + const end = start + perPage + const paginatedInterviews = _.slice(sortedInterviews, start, end) + + return { + total: sortedInterviews.length, + page, + perPage, + result: paginatedInterviews + } + } catch (err) { + logger.logFullError(err, { component: 'InterviewService', context: 'searchInterviews' }) + } + logger.info({ component: 'InterviewService', context: 'searchInterviews', message: 'fallback to DB query' }) + const filter = { + [Op.and]: [{ jobCandidateId }] + } + // apply filtering based on criteria + _.each(_.pick(criteria, ['status', 'createdAt', 'updatedAt']), (value, key) => { + filter[Op.and].push({ [key]: value }) + }) + const interviews = await Interview.findAll({ + where: filter, + offset: ((page - 1) * perPage), + limit: perPage, + order: [[criteria.sortBy, criteria.sortOrder]] + }) + return { + fromDb: true, + total: interviews.length, + page, + perPage, + result: _.map(interviews, interview => interview.dataValues) + } +} + +searchInterviews.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + criteria: Joi.object().keys({ + page: Joi.page(), + perPage: Joi.perPage(), + sortBy: Joi.string().valid('round', 'createdAt', 'updatedAt').default('createdAt'), + sortOrder: Joi.string().valid('desc', 'asc').default('desc'), + createdAt: Joi.date(), + updatedAt: Joi.date(), + status: Joi.interviewStatus() + }).required() +}).required() + +/** + * Updates the status of completed (based on startTimestamp) interviews. + * If the startTimestamp of an interview is less than (or equal) the (currentDateTime - 1 hour) + * it's considered as completed. + */ +async function updateCompletedInterviews () { + logger.info({ component: 'InterviewService', context: 'updateCompletedInterviews', message: 'Running the scheduled job...' }) + const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000) + const [affectedCount, updatedRows] = await Interview.update( + // '00000000-0000-0000-0000-000000000000' - to indicate it's updated by the system job + { status: InterviewConstants.Status.Completed, updatedBy: '00000000-0000-0000-0000-000000000000' }, + { + where: { + status: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], + startTimestamp: { + [Op.lte]: oneHourAgo + } + }, + returning: true + } + ) + + // post event if there are affected/updated interviews + if (affectedCount > 0) { + // payload format: + // { + // jobCandidateId: { interviewId: { affectedFields }, interviewId2: { affectedFields }, ... }, + // jobCandidateId2: { interviewId: { affectedFields }, interviewId2: { affectedFields }, ... }, + // ... + // } + const bulkUpdatePayload = {} + // construct payload + _.forEach(updatedRows, row => { + const interview = row.toJSON() + const affectedFields = _.pick(interview, ['status', 'updatedBy', 'updatedAt']) + _.set(bulkUpdatePayload, [interview.jobCandidateId, interview.id], affectedFields) + }) + // post event + await helper.postEvent(config.TAAS_INTERVIEW_BULK_UPDATE_TOPIC, bulkUpdatePayload) + } + logger.info({ component: 'InterviewService', context: 'updateCompletedInterviews', message: `Completed running. Updated ${affectedCount} interviews.` }) +} + +module.exports = { + getInterviewByRound, + requestInterview, + partiallyUpdateInterview, + searchInterviews, + updateCompletedInterviews +} diff --git a/src/services/JobCandidateService.js b/src/services/JobCandidateService.js index 0dec8a18..392d0af6 100644 --- a/src/services/JobCandidateService.js +++ b/src/services/JobCandidateService.js @@ -8,6 +8,7 @@ const config = require('config') const HttpStatus = require('http-status-codes') const { Op } = require('sequelize') const { v4: uuid } = require('uuid') +const { Scopes } = require('../../app-constants') const helper = require('../common/helper') const logger = require('../common/logger') const errors = require('../common/errors') @@ -31,6 +32,24 @@ async function _checkUserPermissionForGetJobCandidate (currentUser, jobId) { } } +/** + * Returns field omit list, based on user access level. + * + * @param {Object} currentUser the user who perform this operation. + * @returns {Array} the field list to omit from the jobCandidate object + */ +function getJobCandidateOmitList (currentUser) { + // check M2M scopes for Interviews + if (currentUser.isMachine) { + const interviewsAllowedScopes = [Scopes.READ_INTERVIEW, Scopes.ALL_INTERVIEW] + if (!currentUser.scopes || !helper.checkIfExists(interviewsAllowedScopes, currentUser.scopes)) { + return ['interviews'] + } + return [] + } + return currentUser.hasManagePermission ? [] : ['interviews'] +} + /** * Get jobCandidate by id * @param {Object} currentUser the user who perform this operation. @@ -39,6 +58,7 @@ async function _checkUserPermissionForGetJobCandidate (currentUser, jobId) { * @returns {Object} the jobCandidate */ async function getJobCandidate (currentUser, id, fromDb = false) { + const omitList = getJobCandidateOmitList(currentUser) if (!fromDb) { try { const jobCandidate = await esClient.get({ @@ -49,7 +69,7 @@ async function getJobCandidate (currentUser, id, fromDb = false) { await _checkUserPermissionForGetJobCandidate(currentUser, jobCandidate.body._source.jobId) // check user permisson const jobCandidateRecord = { id: jobCandidate.body._id, ...jobCandidate.body._source } - return jobCandidateRecord + return _.omit(jobCandidateRecord, omitList) } catch (err) { if (helper.isDocumentMissingException(err)) { throw new errors.NotFoundError(`id: ${id} "JobCandidate" not found`) @@ -61,7 +81,13 @@ async function getJobCandidate (currentUser, id, fromDb = false) { } } logger.info({ component: 'JobCandidateService', context: 'getJobCandidate', message: 'try to query db for data' }) - const jobCandidate = await JobCandidate.findById(id) + // include interviews if user has permission + const include = [] + const hasInterviewPermision = !_.includes(omitList, 'interviews') + if (hasInterviewPermision) { + include.push({ model: models.Interview, as: 'interviews' }) + } + const jobCandidate = await JobCandidate.findById(id, include) await _checkUserPermissionForGetJobCandidate(currentUser, jobCandidate.jobId) // check user permission @@ -215,6 +241,7 @@ async function searchJobCandidates (currentUser, criteria) { await JobService.getJob(currentUser, criteria.jobId) // check whether user can access the job associated with the jobCandidate } + const omitList = getJobCandidateOmitList(currentUser) const page = criteria.page > 0 ? criteria.page : 1 const perPage = criteria.perPage > 0 ? criteria.perPage : 20 if (!criteria.sortBy) { @@ -260,7 +287,7 @@ async function searchJobCandidates (currentUser, criteria) { result: _.map(body.hits.hits, (hit) => { const obj = _.cloneDeep(hit._source) obj.id = hit._id - return obj + return _.omit(obj, omitList) }) } } catch (err) { @@ -271,8 +298,17 @@ async function searchJobCandidates (currentUser, criteria) { _.each(_.pick(criteria, ['jobId', 'userId', 'status', 'externalId']), (value, key) => { filter[Op.and].push({ [key]: value }) }) + + // include interviews if user has permission + const include = [] + const hasInterviewPermision = !_.includes(omitList, 'interviews') + if (hasInterviewPermision) { + include.push({ model: models.Interview, as: 'interviews' }) + } + const jobCandidates = await JobCandidate.findAll({ where: filter, + include, offset: ((page - 1) * perPage), limit: perPage, order: [[criteria.sortBy, criteria.sortOrder]] @@ -282,7 +318,7 @@ async function searchJobCandidates (currentUser, criteria) { total: jobCandidates.length, page, perPage, - result: _.map(jobCandidates, jobCandidate => jobCandidate.dataValues) + result: _.map(jobCandidates, jobCandidate => _.omit(jobCandidate.dataValues, omitList)) } } diff --git a/src/services/TeamService.js b/src/services/TeamService.js index 0519543e..459e6228 100644 --- a/src/services/TeamService.js +++ b/src/services/TeamService.js @@ -5,7 +5,6 @@ const _ = require('lodash') const Joi = require('joi') const dateFNS = require('date-fns') -const Handlebars = require('handlebars') const config = require('config') const emailTemplateConfig = require('../../config/email_template.config') const helper = require('../common/helper') @@ -16,9 +15,9 @@ const ResourceBookingService = require('./ResourceBookingService') const emailTemplates = _.mapValues(emailTemplateConfig, (template) => { return { - subjectTemplate: Handlebars.compile(template.subject), - bodyTemplate: Handlebars.compile(template.body), + from: template.from, recipients: template.recipients, + cc: template.cc, sendgridTemplateId: template.sendgridTemplateId } }) @@ -316,14 +315,21 @@ getTeamJob.schema = Joi.object().keys({ */ async function sendEmail (currentUser, data) { const template = emailTemplates[data.template] + + const dataCC = data.cc || [] + const templateCC = template.cc || [] + const dataRecipients = data.recipients || [] + const templateRecipients = template.recipients || [] + await helper.postEvent(config.EMAIL_TOPIC, { - data: { - subject: template.subjectTemplate(data.data), - body: template.bodyTemplate(data.data) - }, + data: data.data, // substitutions sendgrid_template_id: template.sendgridTemplateId, version: 'v3', - recipients: template.recipients + // override template if coming data already have the 'from' address + from: data.from || template.from, + // create a set of uniq. recipients & CCs, from both coming data & template + recipients: _.uniq([...dataRecipients, ...templateRecipients]), + cc: _.uniq([...dataCC, ...templateCC]) }) } @@ -331,7 +337,10 @@ sendEmail.schema = Joi.object().keys({ currentUser: Joi.object().required(), data: Joi.object().keys({ template: Joi.string().valid(...Object.keys(emailTemplates)).required(), - data: Joi.object().required() + data: Joi.object().required(), + from: Joi.string().email(), + recipients: Joi.array().items(Joi.string().email()).allow(null), + cc: Joi.array().items(Joi.string().email()).allow(null) }).required() }).required()