diff --git a/.eslintrc.json b/.eslintrc.json index 86e75217..3282824e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,11 +15,12 @@ "env": { "jest": true }, - "ignorePatterns": ["**/docs/*"], + "ignorePatterns": ["**/docs/*", "backend/tests/jest_sequencer.js"], "rules": { "@typescript-eslint/no-unused-vars": "error", "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-var-requires": 0, "@typescript-eslint/no-explicit-any": [ "error", { "fixToUnknown": true } diff --git a/.github/workflows/backendCI.yml b/.github/workflows/backendCI.yml index 5b6f2005..5d8315f9 100644 --- a/.github/workflows/backendCI.yml +++ b/.github/workflows/backendCI.yml @@ -8,50 +8,53 @@ on: # Should run all tests and upload the codecoverage on main push: - branches: [main] - + branches: [ main ] + jobs: ci: runs-on: ubuntu-latest services: - postgres: # this is for the integration testing of the orm functions - image: postgres:14.2 - env: - POSTGRES_USER: prisma - POSTGRES_PASSWORD: prisma - POSTGRES_DB: tests - ports: - - 5433:5432 - options: - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + postgres: # this is for the integration testing of the orm functions + image: postgres:14.2 + env: + POSTGRES_USER: prisma + POSTGRES_PASSWORD: prisma + POSTGRES_DB: tests + ports: + - 5433:5432 + options: + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - - uses: actions/checkout@v3 - - name: Create Prisma Env File - run: | - touch backend/prisma/.env - echo DATABASE_URL="postgresql://osoc2:password@db:5432/osoc2?connect_timeout=30&pool_timeout=30" >> backend/prisma/.env - cat backend/prisma/.env - - name: Use Node.js 17.x - uses: actions/setup-node@v3 - with: - node-version: 17.x - - - run: npm install - working-directory: backend - - # push the db scheme to the db container - - name: Push schema to docker file - run: npx dotenv -e prisma/.env.test -- npx prisma db push - working-directory: backend - - - name: Coverage Report - uses: ArtiomTr/jest-coverage-report-action@v2 - with: + - uses: actions/checkout@v3 + - name: Create Prisma Env File + run: | + touch backend/prisma/.env + echo DATABASE_URL="postgresql://osoc2:password@db:5432/osoc2?connect_timeout=30&pool_timeout=30" >> backend/prisma/.env + cat backend/prisma/.env + - name: Use Node.js 17.x + uses: actions/setup-node@v3 + with: + node-version: 17.x + + - run: npm install + working-directory: backend + + # push the db scheme to the db container + - name: Push schema to docker file + run: npx dotenv -e prisma/.env.test -- npx prisma db push working-directory: backend - skip-step: install - annotations: failed-tests + + - name: Setup environment + run: echo 'NODE_OPTIONS="--max-old-space-size=4096"' >> $GITHUB_ENV + + - name: Coverage Report + uses: ArtiomTr/jest-coverage-report-action@v2 + with: + working-directory: backend + skip-step: install + annotations: failed-tests diff --git a/.github/workflows/frontendCI.yml b/.github/workflows/frontendCI.yml index 6d800126..56f294a9 100644 --- a/.github/workflows/frontendCI.yml +++ b/.github/workflows/frontendCI.yml @@ -9,7 +9,7 @@ on: # Should run all tests and upload the codecoverage on main push: - branches: [main] + branches: [ main ] jobs: ci: @@ -23,7 +23,13 @@ jobs: - run: npm install working-directory: frontend - - run: npm run build --if-present - working-directory: frontend - - run: npm test --if-present + - run: npm run build working-directory: frontend + + - name: Coverage Report + uses: ArtiomTr/jest-coverage-report-action@v2 + with: + test-script: npm test + working-directory: frontend + skip-step: install + annotations: failed-tests \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index 7daa49f7..febde2d0 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18.0.0 +FROM node:18.2.0 # Create app directory WORKDIR /app diff --git a/backend/config.json b/backend/config.json index d1a6c12a..4b6c95c6 100644 --- a/backend/config.json +++ b/backend/config.json @@ -1,6 +1,4 @@ { - "port": 4096, - "apiErrors": { "invalidID": { "http": 204, @@ -76,6 +74,18 @@ "http": 400, "reason": "Failed to update your password. Perhaps you used an invalid key?" } + }, + "studentSuggestion": { + "insufficientRights": { + "http": 403, + "reason": "Failed to create suggestion. Can only create suggestions for the most recent osoc edition." + } + }, + "modifyProject": { + "insufficientRights": { + "http": 403, + "reason": "Failed to modify project. Can only modify projects of the most recent osoc edition." + } } }, @@ -85,11 +95,17 @@ ], "preferred": "/api-osoc", "authScheme": "auth/osoc2", - "defaultUserId": 3 + "defaultUserId": 3, + "port": 4096, + "pageSize": 10 }, "email": { "from": "'OSOC2 Account Recovery' ", "header": "OSOC2 Recovery Code" + }, + + "encryption": { + "encryptionRounds": 8 } } diff --git a/backend/docs/assets/search.js b/backend/docs/assets/search.js index af36ccda..87bcc4ad 100644 --- a/backend/docs/assets/search.js +++ b/backend/docs/assets/search.js @@ -1 +1 @@ -window.searchData = JSON.parse("{\"kinds\":{\"2\":\"Module\",\"32\":\"Variable\",\"64\":\"Function\",\"256\":\"Interface\",\"1024\":\"Property\",\"65536\":\"Type literal\",\"4194304\":\"Type alias\"},\"rows\":[{\"id\":0,\"kind\":2,\"name\":\"orm_functions/applied_role\",\"url\":\"modules/orm_functions_applied_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":1,\"kind\":64,\"name\":\"createAppliedRole\",\"url\":\"modules/orm_functions_applied_role.html#createAppliedRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/applied_role\"},{\"id\":2,\"kind\":64,\"name\":\"getAppliedRolesByJobApplication\",\"url\":\"modules/orm_functions_applied_role.html#getAppliedRolesByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/applied_role\"},{\"id\":3,\"kind\":64,\"name\":\"deleteAppliedRolesByJobApplication\",\"url\":\"modules/orm_functions_applied_role.html#deleteAppliedRolesByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/applied_role\"},{\"id\":4,\"kind\":2,\"name\":\"orm_functions/attachment\",\"url\":\"modules/orm_functions_attachment.html\",\"classes\":\"tsd-kind-module\"},{\"id\":5,\"kind\":64,\"name\":\"createAttachment\",\"url\":\"modules/orm_functions_attachment.html#createAttachment\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":6,\"kind\":64,\"name\":\"deleteAttachment\",\"url\":\"modules/orm_functions_attachment.html#deleteAttachment\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":7,\"kind\":64,\"name\":\"deleteAllAttachmentsForApplication\",\"url\":\"modules/orm_functions_attachment.html#deleteAllAttachmentsForApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":8,\"kind\":64,\"name\":\"getAttachmentById\",\"url\":\"modules/orm_functions_attachment.html#getAttachmentById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":9,\"kind\":2,\"name\":\"orm_functions/contract\",\"url\":\"modules/orm_functions_contract.html\",\"classes\":\"tsd-kind-module\"},{\"id\":10,\"kind\":64,\"name\":\"createContract\",\"url\":\"modules/orm_functions_contract.html#createContract\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":11,\"kind\":64,\"name\":\"updateContract\",\"url\":\"modules/orm_functions_contract.html#updateContract\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":12,\"kind\":64,\"name\":\"removeContractsFromStudent\",\"url\":\"modules/orm_functions_contract.html#removeContractsFromStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":13,\"kind\":64,\"name\":\"removeContract\",\"url\":\"modules/orm_functions_contract.html#removeContract\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":14,\"kind\":64,\"name\":\"contractsForStudent\",\"url\":\"modules/orm_functions_contract.html#contractsForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":15,\"kind\":64,\"name\":\"contractsByProject\",\"url\":\"modules/orm_functions_contract.html#contractsByProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":16,\"kind\":64,\"name\":\"sortedContractsByOsocEdition\",\"url\":\"modules/orm_functions_contract.html#sortedContractsByOsocEdition\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":17,\"kind\":2,\"name\":\"orm_functions/evaluation\",\"url\":\"modules/orm_functions_evaluation.html\",\"classes\":\"tsd-kind-module\"},{\"id\":18,\"kind\":64,\"name\":\"checkIfFinalEvaluationExists\",\"url\":\"modules/orm_functions_evaluation.html#checkIfFinalEvaluationExists\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":19,\"kind\":64,\"name\":\"createEvaluationForStudent\",\"url\":\"modules/orm_functions_evaluation.html#createEvaluationForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":20,\"kind\":64,\"name\":\"updateEvaluationForStudent\",\"url\":\"modules/orm_functions_evaluation.html#updateEvaluationForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":21,\"kind\":64,\"name\":\"getLoginUserByEvaluationId\",\"url\":\"modules/orm_functions_evaluation.html#getLoginUserByEvaluationId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":22,\"kind\":64,\"name\":\"getEvaluationByPartiesFor\",\"url\":\"modules/orm_functions_evaluation.html#getEvaluationByPartiesFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":23,\"kind\":64,\"name\":\"deleteEvaluationsByJobApplication\",\"url\":\"modules/orm_functions_evaluation.html#deleteEvaluationsByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":24,\"kind\":2,\"name\":\"orm_functions/general_purpose\",\"url\":\"modules/orm_functions_general_purpose.html\",\"classes\":\"tsd-kind-module\"},{\"id\":25,\"kind\":64,\"name\":\"addStudentToProject\",\"url\":\"modules/orm_functions_general_purpose.html#addStudentToProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/general_purpose\"},{\"id\":26,\"kind\":2,\"name\":\"orm_functions/job_application\",\"url\":\"modules/orm_functions_job_application.html\",\"classes\":\"tsd-kind-module\"},{\"id\":27,\"kind\":64,\"name\":\"getStudentEvaluationsTotal\",\"url\":\"modules/orm_functions_job_application.html#getStudentEvaluationsTotal\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":28,\"kind\":64,\"name\":\"getStudentEvaluationsFinal\",\"url\":\"modules/orm_functions_job_application.html#getStudentEvaluationsFinal\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":29,\"kind\":64,\"name\":\"getStudentEvaluationsTemp\",\"url\":\"modules/orm_functions_job_application.html#getStudentEvaluationsTemp\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":30,\"kind\":64,\"name\":\"getLatestApplicationRolesForStudent\",\"url\":\"modules/orm_functions_job_application.html#getLatestApplicationRolesForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":31,\"kind\":64,\"name\":\"deleteJobApplicationsFromStudent\",\"url\":\"modules/orm_functions_job_application.html#deleteJobApplicationsFromStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":32,\"kind\":64,\"name\":\"changeEmailStatusOfJobApplication\",\"url\":\"modules/orm_functions_job_application.html#changeEmailStatusOfJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":33,\"kind\":64,\"name\":\"deleteJobApplication\",\"url\":\"modules/orm_functions_job_application.html#deleteJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":34,\"kind\":64,\"name\":\"createJobApplication\",\"url\":\"modules/orm_functions_job_application.html#createJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":35,\"kind\":64,\"name\":\"getLatestJobApplicationOfStudent\",\"url\":\"modules/orm_functions_job_application.html#getLatestJobApplicationOfStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":36,\"kind\":64,\"name\":\"getJobApplication\",\"url\":\"modules/orm_functions_job_application.html#getJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":37,\"kind\":64,\"name\":\"getJobApplicationByYear\",\"url\":\"modules/orm_functions_job_application.html#getJobApplicationByYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":38,\"kind\":2,\"name\":\"orm_functions/job_application_skill\",\"url\":\"modules/orm_functions_job_application_skill.html\",\"classes\":\"tsd-kind-module\"},{\"id\":39,\"kind\":64,\"name\":\"createJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#createJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":40,\"kind\":64,\"name\":\"getAllJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#getAllJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":41,\"kind\":64,\"name\":\"getAllJobApplicationSkillByJobApplication\",\"url\":\"modules/orm_functions_job_application_skill.html#getAllJobApplicationSkillByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":42,\"kind\":64,\"name\":\"getJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#getJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":43,\"kind\":64,\"name\":\"updateJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#updateJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":44,\"kind\":64,\"name\":\"deleteJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#deleteJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":45,\"kind\":64,\"name\":\"deleteSkillsByJobApplicationId\",\"url\":\"modules/orm_functions_job_application_skill.html#deleteSkillsByJobApplicationId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":46,\"kind\":2,\"name\":\"orm_functions/language\",\"url\":\"modules/orm_functions_language.html\",\"classes\":\"tsd-kind-module\"},{\"id\":47,\"kind\":64,\"name\":\"createLanguage\",\"url\":\"modules/orm_functions_language.html#createLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":48,\"kind\":64,\"name\":\"getAllLanguages\",\"url\":\"modules/orm_functions_language.html#getAllLanguages\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":49,\"kind\":64,\"name\":\"getLanguage\",\"url\":\"modules/orm_functions_language.html#getLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":50,\"kind\":64,\"name\":\"getLanguageByName\",\"url\":\"modules/orm_functions_language.html#getLanguageByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":51,\"kind\":64,\"name\":\"updateLanguage\",\"url\":\"modules/orm_functions_language.html#updateLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":52,\"kind\":64,\"name\":\"deleteLanguage\",\"url\":\"modules/orm_functions_language.html#deleteLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":53,\"kind\":64,\"name\":\"deleteLanguageByName\",\"url\":\"modules/orm_functions_language.html#deleteLanguageByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":54,\"kind\":2,\"name\":\"orm_functions/login_user\",\"url\":\"modules/orm_functions_login_user.html\",\"classes\":\"tsd-kind-module\"},{\"id\":55,\"kind\":64,\"name\":\"createLoginUser\",\"url\":\"modules/orm_functions_login_user.html#createLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":56,\"kind\":64,\"name\":\"getAllLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#getAllLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":57,\"kind\":64,\"name\":\"getPasswordLoginUserByPerson\",\"url\":\"modules/orm_functions_login_user.html#getPasswordLoginUserByPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":58,\"kind\":64,\"name\":\"getPasswordLoginUser\",\"url\":\"modules/orm_functions_login_user.html#getPasswordLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":59,\"kind\":64,\"name\":\"searchLoginUserByPerson\",\"url\":\"modules/orm_functions_login_user.html#searchLoginUserByPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":60,\"kind\":64,\"name\":\"searchAllAdminLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#searchAllAdminLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":61,\"kind\":64,\"name\":\"searchAllCoachLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#searchAllCoachLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":62,\"kind\":64,\"name\":\"searchAllAdminAndCoachLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#searchAllAdminAndCoachLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":63,\"kind\":64,\"name\":\"updateLoginUser\",\"url\":\"modules/orm_functions_login_user.html#updateLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":64,\"kind\":64,\"name\":\"deleteLoginUserById\",\"url\":\"modules/orm_functions_login_user.html#deleteLoginUserById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":65,\"kind\":64,\"name\":\"deleteLoginUserByPersonId\",\"url\":\"modules/orm_functions_login_user.html#deleteLoginUserByPersonId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":66,\"kind\":64,\"name\":\"getLoginUserById\",\"url\":\"modules/orm_functions_login_user.html#getLoginUserById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":67,\"kind\":64,\"name\":\"filterLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#filterLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":68,\"kind\":64,\"name\":\"setCoach\",\"url\":\"modules/orm_functions_login_user.html#setCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":69,\"kind\":64,\"name\":\"setAdmin\",\"url\":\"modules/orm_functions_login_user.html#setAdmin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":70,\"kind\":2,\"name\":\"orm_functions/orm_types\",\"url\":\"modules/orm_functions_orm_types.html\",\"classes\":\"tsd-kind-module\"},{\"id\":71,\"kind\":256,\"name\":\"CreatePerson\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":72,\"kind\":1024,\"name\":\"firstname\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#firstname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":73,\"kind\":1024,\"name\":\"lastname\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#lastname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":74,\"kind\":1024,\"name\":\"github\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#github\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":75,\"kind\":1024,\"name\":\"email\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#email\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":76,\"kind\":1024,\"name\":\"github_id\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#github_id\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":77,\"kind\":256,\"name\":\"UpdatePerson\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":78,\"kind\":1024,\"name\":\"personId\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#personId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":79,\"kind\":1024,\"name\":\"firstname\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#firstname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":80,\"kind\":1024,\"name\":\"lastname\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#lastname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":81,\"kind\":1024,\"name\":\"github\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#github\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":82,\"kind\":1024,\"name\":\"email\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#email\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":83,\"kind\":256,\"name\":\"CreateLoginUser\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":84,\"kind\":1024,\"name\":\"personId\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#personId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":85,\"kind\":1024,\"name\":\"password\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#password\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":86,\"kind\":1024,\"name\":\"isAdmin\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#isAdmin\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":87,\"kind\":1024,\"name\":\"isCoach\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#isCoach\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":88,\"kind\":1024,\"name\":\"accountStatus\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#accountStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":89,\"kind\":256,\"name\":\"UpdateLoginUser\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":90,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":91,\"kind\":1024,\"name\":\"password\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#password\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":92,\"kind\":1024,\"name\":\"isAdmin\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#isAdmin\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":93,\"kind\":1024,\"name\":\"isCoach\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#isCoach\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":94,\"kind\":1024,\"name\":\"accountStatus\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#accountStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":95,\"kind\":256,\"name\":\"CreateStudent\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":96,\"kind\":1024,\"name\":\"personId\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#personId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":97,\"kind\":1024,\"name\":\"gender\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#gender\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":98,\"kind\":1024,\"name\":\"pronouns\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#pronouns\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":99,\"kind\":1024,\"name\":\"phoneNumber\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#phoneNumber\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":100,\"kind\":1024,\"name\":\"nickname\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#nickname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":101,\"kind\":1024,\"name\":\"alumni\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#alumni\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":102,\"kind\":256,\"name\":\"UpdateStudent\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":103,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":104,\"kind\":1024,\"name\":\"gender\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#gender\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":105,\"kind\":1024,\"name\":\"pronouns\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#pronouns\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":106,\"kind\":1024,\"name\":\"phoneNumber\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#phoneNumber\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":107,\"kind\":1024,\"name\":\"nickname\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#nickname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":108,\"kind\":1024,\"name\":\"alumni\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#alumni\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":109,\"kind\":256,\"name\":\"CreateEvaluationForStudent\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":110,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":111,\"kind\":1024,\"name\":\"jobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#jobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":112,\"kind\":1024,\"name\":\"decision\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#decision\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":113,\"kind\":1024,\"name\":\"motivation\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#motivation\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":114,\"kind\":1024,\"name\":\"isFinal\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#isFinal\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":115,\"kind\":256,\"name\":\"UpdateEvaluationForStudent\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":116,\"kind\":1024,\"name\":\"evaluation_id\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#evaluation_id\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":117,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":118,\"kind\":1024,\"name\":\"decision\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#decision\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":119,\"kind\":1024,\"name\":\"motivation\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#motivation\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":120,\"kind\":256,\"name\":\"CreateContract\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":121,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":122,\"kind\":1024,\"name\":\"projectRoleId\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#projectRoleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":123,\"kind\":1024,\"name\":\"information\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#information\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":124,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":125,\"kind\":1024,\"name\":\"contractStatus\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#contractStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":126,\"kind\":256,\"name\":\"UpdateContract\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":127,\"kind\":1024,\"name\":\"contractId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#contractId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":128,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":129,\"kind\":1024,\"name\":\"information\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#information\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":130,\"kind\":1024,\"name\":\"contractStatus\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#contractStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":131,\"kind\":1024,\"name\":\"projectRoleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#projectRoleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":132,\"kind\":256,\"name\":\"CreateJobApplication\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":133,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":134,\"kind\":1024,\"name\":\"responsibilities\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#responsibilities\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":135,\"kind\":1024,\"name\":\"funFact\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#funFact\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":136,\"kind\":1024,\"name\":\"studentVolunteerInfo\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#studentVolunteerInfo\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":137,\"kind\":1024,\"name\":\"studentCoach\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#studentCoach\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":138,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":139,\"kind\":1024,\"name\":\"edus\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#edus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":140,\"kind\":1024,\"name\":\"eduLevel\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduLevel\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":141,\"kind\":1024,\"name\":\"eduDuration\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduDuration\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":142,\"kind\":1024,\"name\":\"eduYear\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduYear\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":143,\"kind\":1024,\"name\":\"eduInstitute\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduInstitute\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":144,\"kind\":1024,\"name\":\"emailStatus\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#emailStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":145,\"kind\":1024,\"name\":\"createdAt\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#createdAt\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":146,\"kind\":256,\"name\":\"UpdateOsoc\",\"url\":\"interfaces/orm_functions_orm_types.UpdateOsoc.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":147,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateOsoc.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateOsoc\"},{\"id\":148,\"kind\":1024,\"name\":\"year\",\"url\":\"interfaces/orm_functions_orm_types.UpdateOsoc.html#year\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateOsoc\"},{\"id\":149,\"kind\":256,\"name\":\"CreateProject\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":150,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":151,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":152,\"kind\":1024,\"name\":\"partner\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#partner\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":153,\"kind\":1024,\"name\":\"startDate\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#startDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":154,\"kind\":1024,\"name\":\"endDate\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#endDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":155,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":156,\"kind\":256,\"name\":\"UpdateProject\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":157,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":158,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":159,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":160,\"kind\":1024,\"name\":\"partner\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#partner\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":161,\"kind\":1024,\"name\":\"startDate\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#startDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":162,\"kind\":1024,\"name\":\"endDate\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#endDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":163,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":164,\"kind\":256,\"name\":\"CreateProjectRole\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":165,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectRole\"},{\"id\":166,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectRole\"},{\"id\":167,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectRole\"},{\"id\":168,\"kind\":256,\"name\":\"UpdateProjectRole\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":169,\"kind\":1024,\"name\":\"projectRoleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#projectRoleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":170,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":171,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":172,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":173,\"kind\":256,\"name\":\"UpdateRole\",\"url\":\"interfaces/orm_functions_orm_types.UpdateRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":174,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateRole\"},{\"id\":175,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateRole.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateRole\"},{\"id\":176,\"kind\":256,\"name\":\"UpdateLanguage\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLanguage.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":177,\"kind\":1024,\"name\":\"languageId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLanguage.html#languageId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLanguage\"},{\"id\":178,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLanguage.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLanguage\"},{\"id\":179,\"kind\":256,\"name\":\"CreateJobApplicationSkill\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":180,\"kind\":1024,\"name\":\"jobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#jobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":181,\"kind\":1024,\"name\":\"skill\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#skill\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":182,\"kind\":1024,\"name\":\"languageId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#languageId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":183,\"kind\":1024,\"name\":\"level\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#level\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":184,\"kind\":1024,\"name\":\"isPreferred\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#isPreferred\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":185,\"kind\":1024,\"name\":\"isBest\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#isBest\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":186,\"kind\":256,\"name\":\"UpdateJobApplicationSkill\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":187,\"kind\":1024,\"name\":\"JobApplicationSkillId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#JobApplicationSkillId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":188,\"kind\":1024,\"name\":\"JobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#JobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":189,\"kind\":1024,\"name\":\"skill\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#skill\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":190,\"kind\":1024,\"name\":\"languageId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#languageId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":191,\"kind\":1024,\"name\":\"level\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#level\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":192,\"kind\":1024,\"name\":\"isPreferred\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#isPreferred\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":193,\"kind\":1024,\"name\":\"is_best\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#is_best\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":194,\"kind\":256,\"name\":\"AddStudentToProject\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":195,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":196,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":197,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":198,\"kind\":1024,\"name\":\"roleName\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#roleName\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":199,\"kind\":1024,\"name\":\"information\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#information\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":200,\"kind\":256,\"name\":\"CreateProjectUser\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectUser.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":201,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectUser.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectUser\"},{\"id\":202,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectUser.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectUser\"},{\"id\":203,\"kind\":256,\"name\":\"CreateAppliedRole\",\"url\":\"interfaces/orm_functions_orm_types.CreateAppliedRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":204,\"kind\":1024,\"name\":\"jobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.CreateAppliedRole.html#jobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateAppliedRole\"},{\"id\":205,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.CreateAppliedRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateAppliedRole\"},{\"id\":206,\"kind\":256,\"name\":\"CreateTemplate\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":207,\"kind\":1024,\"name\":\"ownerId\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#ownerId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":208,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":209,\"kind\":1024,\"name\":\"content\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#content\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":210,\"kind\":1024,\"name\":\"subject\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#subject\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":211,\"kind\":1024,\"name\":\"cc\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#cc\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":212,\"kind\":256,\"name\":\"UpdateTemplate\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":213,\"kind\":1024,\"name\":\"templateId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#templateId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":214,\"kind\":1024,\"name\":\"ownerId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#ownerId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":215,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":216,\"kind\":1024,\"name\":\"content\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#content\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":217,\"kind\":1024,\"name\":\"subject\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#subject\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":218,\"kind\":1024,\"name\":\"cc\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#cc\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":219,\"kind\":4194304,\"name\":\"FilterSort\",\"url\":\"modules/orm_functions_orm_types.html#FilterSort\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":220,\"kind\":4194304,\"name\":\"FilterString\",\"url\":\"modules/orm_functions_orm_types.html#FilterString\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":221,\"kind\":4194304,\"name\":\"FilterNumber\",\"url\":\"modules/orm_functions_orm_types.html#FilterNumber\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":222,\"kind\":4194304,\"name\":\"FilterNumberArray\",\"url\":\"modules/orm_functions_orm_types.html#FilterNumberArray\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":223,\"kind\":4194304,\"name\":\"FilterStringArray\",\"url\":\"modules/orm_functions_orm_types.html#FilterStringArray\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":224,\"kind\":4194304,\"name\":\"FilterBoolean\",\"url\":\"modules/orm_functions_orm_types.html#FilterBoolean\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":225,\"kind\":2,\"name\":\"orm_functions/osoc\",\"url\":\"modules/orm_functions_osoc.html\",\"classes\":\"tsd-kind-module\"},{\"id\":226,\"kind\":64,\"name\":\"createOsoc\",\"url\":\"modules/orm_functions_osoc.html#createOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":227,\"kind\":64,\"name\":\"getAllOsoc\",\"url\":\"modules/orm_functions_osoc.html#getAllOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":228,\"kind\":64,\"name\":\"getLatestOsoc\",\"url\":\"modules/orm_functions_osoc.html#getLatestOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":229,\"kind\":64,\"name\":\"getOsocByYear\",\"url\":\"modules/orm_functions_osoc.html#getOsocByYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":230,\"kind\":64,\"name\":\"getOsocBeforeYear\",\"url\":\"modules/orm_functions_osoc.html#getOsocBeforeYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":231,\"kind\":64,\"name\":\"getOsocAfterYear\",\"url\":\"modules/orm_functions_osoc.html#getOsocAfterYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":232,\"kind\":64,\"name\":\"updateOsoc\",\"url\":\"modules/orm_functions_osoc.html#updateOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":233,\"kind\":64,\"name\":\"deleteOsoc\",\"url\":\"modules/orm_functions_osoc.html#deleteOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":234,\"kind\":64,\"name\":\"deleteOsocByYear\",\"url\":\"modules/orm_functions_osoc.html#deleteOsocByYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":235,\"kind\":64,\"name\":\"deleteOsocFromDB\",\"url\":\"modules/orm_functions_osoc.html#deleteOsocFromDB\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":236,\"kind\":64,\"name\":\"getNewestOsoc\",\"url\":\"modules/orm_functions_osoc.html#getNewestOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":237,\"kind\":64,\"name\":\"filterOsocs\",\"url\":\"modules/orm_functions_osoc.html#filterOsocs\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":238,\"kind\":2,\"name\":\"orm_functions/password_reset\",\"url\":\"modules/orm_functions_password_reset.html\",\"classes\":\"tsd-kind-module\"},{\"id\":239,\"kind\":64,\"name\":\"createOrUpdateReset\",\"url\":\"modules/orm_functions_password_reset.html#createOrUpdateReset\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":240,\"kind\":64,\"name\":\"findResetByCode\",\"url\":\"modules/orm_functions_password_reset.html#findResetByCode\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":241,\"kind\":64,\"name\":\"deleteResetWithLoginUser\",\"url\":\"modules/orm_functions_password_reset.html#deleteResetWithLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":242,\"kind\":64,\"name\":\"deleteResetWithResetId\",\"url\":\"modules/orm_functions_password_reset.html#deleteResetWithResetId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":243,\"kind\":2,\"name\":\"orm_functions/person\",\"url\":\"modules/orm_functions_person.html\",\"classes\":\"tsd-kind-module\"},{\"id\":244,\"kind\":64,\"name\":\"createPerson\",\"url\":\"modules/orm_functions_person.html#createPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":245,\"kind\":64,\"name\":\"getAllPersons\",\"url\":\"modules/orm_functions_person.html#getAllPersons\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":246,\"kind\":64,\"name\":\"getPasswordPersonByEmail\",\"url\":\"modules/orm_functions_person.html#getPasswordPersonByEmail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":247,\"kind\":64,\"name\":\"getPasswordPersonByGithub\",\"url\":\"modules/orm_functions_person.html#getPasswordPersonByGithub\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":248,\"kind\":64,\"name\":\"searchPersonByName\",\"url\":\"modules/orm_functions_person.html#searchPersonByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":249,\"kind\":64,\"name\":\"searchPersonByLogin\",\"url\":\"modules/orm_functions_person.html#searchPersonByLogin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":250,\"kind\":64,\"name\":\"updatePerson\",\"url\":\"modules/orm_functions_person.html#updatePerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":251,\"kind\":64,\"name\":\"deletePersonById\",\"url\":\"modules/orm_functions_person.html#deletePersonById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":252,\"kind\":2,\"name\":\"orm_functions/project\",\"url\":\"modules/orm_functions_project.html\",\"classes\":\"tsd-kind-module\"},{\"id\":253,\"kind\":64,\"name\":\"createProject\",\"url\":\"modules/orm_functions_project.html#createProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":254,\"kind\":64,\"name\":\"getAllProjects\",\"url\":\"modules/orm_functions_project.html#getAllProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":255,\"kind\":64,\"name\":\"getProjectById\",\"url\":\"modules/orm_functions_project.html#getProjectById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":256,\"kind\":64,\"name\":\"getProjectByName\",\"url\":\"modules/orm_functions_project.html#getProjectByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":257,\"kind\":64,\"name\":\"getProjectsByOsocEdition\",\"url\":\"modules/orm_functions_project.html#getProjectsByOsocEdition\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":258,\"kind\":64,\"name\":\"getProjectsByPartner\",\"url\":\"modules/orm_functions_project.html#getProjectsByPartner\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":259,\"kind\":64,\"name\":\"getProjectsByStartDate\",\"url\":\"modules/orm_functions_project.html#getProjectsByStartDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":260,\"kind\":64,\"name\":\"getProjectsStartedAfterDate\",\"url\":\"modules/orm_functions_project.html#getProjectsStartedAfterDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":261,\"kind\":64,\"name\":\"getProjectsStartedBeforeDate\",\"url\":\"modules/orm_functions_project.html#getProjectsStartedBeforeDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":262,\"kind\":64,\"name\":\"getProjectsByEndDate\",\"url\":\"modules/orm_functions_project.html#getProjectsByEndDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":263,\"kind\":64,\"name\":\"getProjectsEndedAfterDate\",\"url\":\"modules/orm_functions_project.html#getProjectsEndedAfterDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":264,\"kind\":64,\"name\":\"getProjectsEndedBeforeDate\",\"url\":\"modules/orm_functions_project.html#getProjectsEndedBeforeDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":265,\"kind\":64,\"name\":\"getProjectsByNumberPositions\",\"url\":\"modules/orm_functions_project.html#getProjectsByNumberPositions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":266,\"kind\":64,\"name\":\"getProjectsLessPositions\",\"url\":\"modules/orm_functions_project.html#getProjectsLessPositions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":267,\"kind\":64,\"name\":\"getProjectsMorePositions\",\"url\":\"modules/orm_functions_project.html#getProjectsMorePositions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":268,\"kind\":64,\"name\":\"updateProject\",\"url\":\"modules/orm_functions_project.html#updateProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":269,\"kind\":64,\"name\":\"deleteProject\",\"url\":\"modules/orm_functions_project.html#deleteProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":270,\"kind\":64,\"name\":\"deleteProjectByOsocEdition\",\"url\":\"modules/orm_functions_project.html#deleteProjectByOsocEdition\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":271,\"kind\":64,\"name\":\"deleteProjectByPartner\",\"url\":\"modules/orm_functions_project.html#deleteProjectByPartner\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":272,\"kind\":64,\"name\":\"filterProjects\",\"url\":\"modules/orm_functions_project.html#filterProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":273,\"kind\":2,\"name\":\"orm_functions/project_role\",\"url\":\"modules/orm_functions_project_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":274,\"kind\":64,\"name\":\"createProjectRole\",\"url\":\"modules/orm_functions_project_role.html#createProjectRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":275,\"kind\":64,\"name\":\"getProjectRolesByProject\",\"url\":\"modules/orm_functions_project_role.html#getProjectRolesByProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":276,\"kind\":64,\"name\":\"getNumberOfRolesByProjectAndRole\",\"url\":\"modules/orm_functions_project_role.html#getNumberOfRolesByProjectAndRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":277,\"kind\":64,\"name\":\"getProjectRoleNamesByProject\",\"url\":\"modules/orm_functions_project_role.html#getProjectRoleNamesByProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":278,\"kind\":64,\"name\":\"updateProjectRole\",\"url\":\"modules/orm_functions_project_role.html#updateProjectRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":279,\"kind\":64,\"name\":\"deleteProjectRole\",\"url\":\"modules/orm_functions_project_role.html#deleteProjectRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":280,\"kind\":64,\"name\":\"getNumberOfFreePositions\",\"url\":\"modules/orm_functions_project_role.html#getNumberOfFreePositions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":281,\"kind\":64,\"name\":\"getProjectRoleById\",\"url\":\"modules/orm_functions_project_role.html#getProjectRoleById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":282,\"kind\":2,\"name\":\"orm_functions/project_user\",\"url\":\"modules/orm_functions_project_user.html\",\"classes\":\"tsd-kind-module\"},{\"id\":283,\"kind\":64,\"name\":\"createProjectUser\",\"url\":\"modules/orm_functions_project_user.html#createProjectUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_user\"},{\"id\":284,\"kind\":64,\"name\":\"getUsersFor\",\"url\":\"modules/orm_functions_project_user.html#getUsersFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_user\"},{\"id\":285,\"kind\":2,\"name\":\"orm_functions/role\",\"url\":\"modules/orm_functions_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":286,\"kind\":64,\"name\":\"createRole\",\"url\":\"modules/orm_functions_role.html#createRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":287,\"kind\":64,\"name\":\"getAllRoles\",\"url\":\"modules/orm_functions_role.html#getAllRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":288,\"kind\":64,\"name\":\"getRole\",\"url\":\"modules/orm_functions_role.html#getRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":289,\"kind\":64,\"name\":\"getRolesByName\",\"url\":\"modules/orm_functions_role.html#getRolesByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":290,\"kind\":64,\"name\":\"getProjectRoleWithRoleName\",\"url\":\"modules/orm_functions_role.html#getProjectRoleWithRoleName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":291,\"kind\":64,\"name\":\"updateRole\",\"url\":\"modules/orm_functions_role.html#updateRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":292,\"kind\":64,\"name\":\"deleteRole\",\"url\":\"modules/orm_functions_role.html#deleteRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":293,\"kind\":64,\"name\":\"deleteRoleByName\",\"url\":\"modules/orm_functions_role.html#deleteRoleByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":294,\"kind\":2,\"name\":\"orm_functions/session_key\",\"url\":\"modules/orm_functions_session_key.html\",\"classes\":\"tsd-kind-module\"},{\"id\":295,\"kind\":64,\"name\":\"addSessionKey\",\"url\":\"modules/orm_functions_session_key.html#addSessionKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":296,\"kind\":64,\"name\":\"checkSessionKey\",\"url\":\"modules/orm_functions_session_key.html#checkSessionKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":297,\"kind\":64,\"name\":\"refreshKey\",\"url\":\"modules/orm_functions_session_key.html#refreshKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":298,\"kind\":64,\"name\":\"removeAllKeysForUser\",\"url\":\"modules/orm_functions_session_key.html#removeAllKeysForUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":299,\"kind\":64,\"name\":\"removeAllKeysForLoginUserId\",\"url\":\"modules/orm_functions_session_key.html#removeAllKeysForLoginUserId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":300,\"kind\":2,\"name\":\"orm_functions/student\",\"url\":\"modules/orm_functions_student.html\",\"classes\":\"tsd-kind-module\"},{\"id\":301,\"kind\":64,\"name\":\"createStudent\",\"url\":\"modules/orm_functions_student.html#createStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":302,\"kind\":64,\"name\":\"getAllStudents\",\"url\":\"modules/orm_functions_student.html#getAllStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":303,\"kind\":64,\"name\":\"getStudent\",\"url\":\"modules/orm_functions_student.html#getStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":304,\"kind\":64,\"name\":\"updateStudent\",\"url\":\"modules/orm_functions_student.html#updateStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":305,\"kind\":64,\"name\":\"deleteStudent\",\"url\":\"modules/orm_functions_student.html#deleteStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":306,\"kind\":64,\"name\":\"searchStudentByGender\",\"url\":\"modules/orm_functions_student.html#searchStudentByGender\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":307,\"kind\":64,\"name\":\"filterStudents\",\"url\":\"modules/orm_functions_student.html#filterStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":308,\"kind\":2,\"name\":\"orm_functions/template\",\"url\":\"modules/orm_functions_template.html\",\"classes\":\"tsd-kind-module\"},{\"id\":309,\"kind\":64,\"name\":\"getAllTemplates\",\"url\":\"modules/orm_functions_template.html#getAllTemplates\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":310,\"kind\":64,\"name\":\"getTemplateById\",\"url\":\"modules/orm_functions_template.html#getTemplateById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":311,\"kind\":64,\"name\":\"getTemplatesByName\",\"url\":\"modules/orm_functions_template.html#getTemplatesByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":312,\"kind\":64,\"name\":\"createTemplate\",\"url\":\"modules/orm_functions_template.html#createTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":313,\"kind\":64,\"name\":\"updateTemplate\",\"url\":\"modules/orm_functions_template.html#updateTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":314,\"kind\":64,\"name\":\"deleteTemplate\",\"url\":\"modules/orm_functions_template.html#deleteTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":315,\"kind\":2,\"name\":\"routes/admin\",\"url\":\"modules/routes_admin.html\",\"classes\":\"tsd-kind-module\"},{\"id\":316,\"kind\":64,\"name\":\"listAdmins\",\"url\":\"modules/routes_admin.html#listAdmins\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":317,\"kind\":64,\"name\":\"modAdmin\",\"url\":\"modules/routes_admin.html#modAdmin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":318,\"kind\":64,\"name\":\"deleteAdmin\",\"url\":\"modules/routes_admin.html#deleteAdmin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":319,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_admin.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":320,\"kind\":2,\"name\":\"routes/coach\",\"url\":\"modules/routes_coach.html\",\"classes\":\"tsd-kind-module\"},{\"id\":321,\"kind\":64,\"name\":\"listCoaches\",\"url\":\"modules/routes_coach.html#listCoaches\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":322,\"kind\":64,\"name\":\"modCoach\",\"url\":\"modules/routes_coach.html#modCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":323,\"kind\":64,\"name\":\"deleteCoach\",\"url\":\"modules/routes_coach.html#deleteCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":324,\"kind\":64,\"name\":\"getCoachRequests\",\"url\":\"modules/routes_coach.html#getCoachRequests\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":325,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_coach.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":326,\"kind\":2,\"name\":\"routes/followup\",\"url\":\"modules/routes_followup.html\",\"classes\":\"tsd-kind-module\"},{\"id\":327,\"kind\":64,\"name\":\"listFollowups\",\"url\":\"modules/routes_followup.html#listFollowups\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/followup\"},{\"id\":328,\"kind\":64,\"name\":\"getFollowup\",\"url\":\"modules/routes_followup.html#getFollowup\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/followup\"},{\"id\":329,\"kind\":64,\"name\":\"updateFollowup\",\"url\":\"modules/routes_followup.html#updateFollowup\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/followup\"},{\"id\":330,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_followup.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/followup\"},{\"id\":331,\"kind\":2,\"name\":\"routes/form\",\"url\":\"modules/routes_form.html\",\"classes\":\"tsd-kind-module\"},{\"id\":332,\"kind\":64,\"name\":\"filterQuestion\",\"url\":\"modules/routes_form.html#filterQuestion\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":333,\"kind\":64,\"name\":\"filterChosenOption\",\"url\":\"modules/routes_form.html#filterChosenOption\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":334,\"kind\":64,\"name\":\"checkWordInAnswer\",\"url\":\"modules/routes_form.html#checkWordInAnswer\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":335,\"kind\":64,\"name\":\"checkQuestionsExist\",\"url\":\"modules/routes_form.html#checkQuestionsExist\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":336,\"kind\":64,\"name\":\"getBirthName\",\"url\":\"modules/routes_form.html#getBirthName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":337,\"kind\":64,\"name\":\"getLastName\",\"url\":\"modules/routes_form.html#getLastName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":338,\"kind\":64,\"name\":\"getEmail\",\"url\":\"modules/routes_form.html#getEmail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":339,\"kind\":64,\"name\":\"jsonToPerson\",\"url\":\"modules/routes_form.html#jsonToPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":340,\"kind\":64,\"name\":\"getPronouns\",\"url\":\"modules/routes_form.html#getPronouns\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":341,\"kind\":64,\"name\":\"getGender\",\"url\":\"modules/routes_form.html#getGender\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":342,\"kind\":64,\"name\":\"getPhoneNumber\",\"url\":\"modules/routes_form.html#getPhoneNumber\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":343,\"kind\":64,\"name\":\"getNickname\",\"url\":\"modules/routes_form.html#getNickname\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":344,\"kind\":64,\"name\":\"getAlumni\",\"url\":\"modules/routes_form.html#getAlumni\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":345,\"kind\":64,\"name\":\"jsonToStudent\",\"url\":\"modules/routes_form.html#jsonToStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":346,\"kind\":64,\"name\":\"getResponsibilities\",\"url\":\"modules/routes_form.html#getResponsibilities\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":347,\"kind\":64,\"name\":\"getFunFact\",\"url\":\"modules/routes_form.html#getFunFact\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":348,\"kind\":64,\"name\":\"getVolunteerInfo\",\"url\":\"modules/routes_form.html#getVolunteerInfo\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":349,\"kind\":64,\"name\":\"isStudentCoach\",\"url\":\"modules/routes_form.html#isStudentCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":350,\"kind\":64,\"name\":\"getEducations\",\"url\":\"modules/routes_form.html#getEducations\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":351,\"kind\":64,\"name\":\"getEducationLevel\",\"url\":\"modules/routes_form.html#getEducationLevel\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":352,\"kind\":64,\"name\":\"getEducationDuration\",\"url\":\"modules/routes_form.html#getEducationDuration\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":353,\"kind\":64,\"name\":\"getEducationYear\",\"url\":\"modules/routes_form.html#getEducationYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":354,\"kind\":64,\"name\":\"getEducationUniversity\",\"url\":\"modules/routes_form.html#getEducationUniversity\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":355,\"kind\":64,\"name\":\"jsonToJobApplication\",\"url\":\"modules/routes_form.html#jsonToJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":356,\"kind\":64,\"name\":\"getMostFluentLanguage\",\"url\":\"modules/routes_form.html#getMostFluentLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":357,\"kind\":64,\"name\":\"getEnglishLevel\",\"url\":\"modules/routes_form.html#getEnglishLevel\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":358,\"kind\":64,\"name\":\"getBestSkill\",\"url\":\"modules/routes_form.html#getBestSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":359,\"kind\":64,\"name\":\"jsonToSkills\",\"url\":\"modules/routes_form.html#jsonToSkills\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":360,\"kind\":64,\"name\":\"getCV\",\"url\":\"modules/routes_form.html#getCV\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":361,\"kind\":64,\"name\":\"getPortfolio\",\"url\":\"modules/routes_form.html#getPortfolio\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":362,\"kind\":64,\"name\":\"getMotivation\",\"url\":\"modules/routes_form.html#getMotivation\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":363,\"kind\":64,\"name\":\"jsonToAttachments\",\"url\":\"modules/routes_form.html#jsonToAttachments\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":364,\"kind\":64,\"name\":\"getAppliedRoles\",\"url\":\"modules/routes_form.html#getAppliedRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":365,\"kind\":64,\"name\":\"jsonToRoles\",\"url\":\"modules/routes_form.html#jsonToRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":366,\"kind\":64,\"name\":\"addPersonToDatabase\",\"url\":\"modules/routes_form.html#addPersonToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":367,\"kind\":64,\"name\":\"addStudentToDatabase\",\"url\":\"modules/routes_form.html#addStudentToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":368,\"kind\":64,\"name\":\"addJobApplicationToDatabase\",\"url\":\"modules/routes_form.html#addJobApplicationToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":369,\"kind\":64,\"name\":\"addSkillsToDatabase\",\"url\":\"modules/routes_form.html#addSkillsToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":370,\"kind\":64,\"name\":\"addAttachmentsToDatabase\",\"url\":\"modules/routes_form.html#addAttachmentsToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":371,\"kind\":64,\"name\":\"addRolesToDatabase\",\"url\":\"modules/routes_form.html#addRolesToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":372,\"kind\":64,\"name\":\"createForm\",\"url\":\"modules/routes_form.html#createForm\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":373,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_form.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":374,\"kind\":2,\"name\":\"routes/form_keys.json\",\"url\":\"modules/routes_form_keys_json.html\",\"classes\":\"tsd-kind-module\"},{\"id\":375,\"kind\":1024,\"name\":\"export=\",\"url\":\"modules/routes_form_keys_json.html#export_\",\"classes\":\"tsd-kind-property tsd-parent-kind-module\",\"parent\":\"routes/form_keys.json\"},{\"id\":376,\"kind\":65536,\"name\":\"__type\",\"url\":\"modules/routes_form_keys_json.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-module\",\"parent\":\"routes/form_keys.json\"},{\"id\":377,\"kind\":1024,\"name\":\"liveInBelgium\",\"url\":\"modules/routes_form_keys_json.html#__type.liveInBelgium\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":378,\"kind\":1024,\"name\":\"volunteerInfo\",\"url\":\"modules/routes_form_keys_json.html#__type.volunteerInfo\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":379,\"kind\":1024,\"name\":\"workInJuly\",\"url\":\"modules/routes_form_keys_json.html#__type.workInJuly\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":380,\"kind\":1024,\"name\":\"responsibilities\",\"url\":\"modules/routes_form_keys_json.html#__type.responsibilities\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":381,\"kind\":1024,\"name\":\"birthName\",\"url\":\"modules/routes_form_keys_json.html#__type.birthName\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":382,\"kind\":1024,\"name\":\"lastName\",\"url\":\"modules/routes_form_keys_json.html#__type.lastName\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":383,\"kind\":1024,\"name\":\"nickname\",\"url\":\"modules/routes_form_keys_json.html#__type.nickname\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":384,\"kind\":1024,\"name\":\"nicknameInput\",\"url\":\"modules/routes_form_keys_json.html#__type.nicknameInput\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":385,\"kind\":1024,\"name\":\"gender\",\"url\":\"modules/routes_form_keys_json.html#__type.gender\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":386,\"kind\":1024,\"name\":\"addPronouns\",\"url\":\"modules/routes_form_keys_json.html#__type.addPronouns\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":387,\"kind\":1024,\"name\":\"preferredPronouns\",\"url\":\"modules/routes_form_keys_json.html#__type.preferredPronouns\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":388,\"kind\":1024,\"name\":\"pronounsInput\",\"url\":\"modules/routes_form_keys_json.html#__type.pronounsInput\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":389,\"kind\":1024,\"name\":\"mostFluentLanguage\",\"url\":\"modules/routes_form_keys_json.html#__type.mostFluentLanguage\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":390,\"kind\":1024,\"name\":\"mostFluentLanguageInput\",\"url\":\"modules/routes_form_keys_json.html#__type.mostFluentLanguageInput\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":391,\"kind\":1024,\"name\":\"englishLevel\",\"url\":\"modules/routes_form_keys_json.html#__type.englishLevel\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":392,\"kind\":1024,\"name\":\"phoneNumber\",\"url\":\"modules/routes_form_keys_json.html#__type.phoneNumber\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":393,\"kind\":1024,\"name\":\"emailAddress\",\"url\":\"modules/routes_form_keys_json.html#__type.emailAddress\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":394,\"kind\":1024,\"name\":\"cvUpload\",\"url\":\"modules/routes_form_keys_json.html#__type.cvUpload\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":395,\"kind\":1024,\"name\":\"cvLink\",\"url\":\"modules/routes_form_keys_json.html#__type.cvLink\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":396,\"kind\":1024,\"name\":\"portfolioUpload\",\"url\":\"modules/routes_form_keys_json.html#__type.portfolioUpload\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":397,\"kind\":1024,\"name\":\"portfolioLink\",\"url\":\"modules/routes_form_keys_json.html#__type.portfolioLink\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":398,\"kind\":1024,\"name\":\"motivationUpload\",\"url\":\"modules/routes_form_keys_json.html#__type.motivationUpload\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":399,\"kind\":1024,\"name\":\"motivationLink\",\"url\":\"modules/routes_form_keys_json.html#__type.motivationLink\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":400,\"kind\":1024,\"name\":\"motivationInput\",\"url\":\"modules/routes_form_keys_json.html#__type.motivationInput\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":401,\"kind\":1024,\"name\":\"funFact\",\"url\":\"modules/routes_form_keys_json.html#__type.funFact\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":402,\"kind\":1024,\"name\":\"edus\",\"url\":\"modules/routes_form_keys_json.html#__type.edus\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":403,\"kind\":1024,\"name\":\"edusInput\",\"url\":\"modules/routes_form_keys_json.html#__type.edusInput\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":404,\"kind\":1024,\"name\":\"eduLevel\",\"url\":\"modules/routes_form_keys_json.html#__type.eduLevel\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":405,\"kind\":1024,\"name\":\"eduLevelInput\",\"url\":\"modules/routes_form_keys_json.html#__type.eduLevelInput\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":406,\"kind\":1024,\"name\":\"eduDuration\",\"url\":\"modules/routes_form_keys_json.html#__type.eduDuration\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":407,\"kind\":1024,\"name\":\"eduYear\",\"url\":\"modules/routes_form_keys_json.html#__type.eduYear\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":408,\"kind\":1024,\"name\":\"eduInstitute\",\"url\":\"modules/routes_form_keys_json.html#__type.eduInstitute\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":409,\"kind\":1024,\"name\":\"appliedRole\",\"url\":\"modules/routes_form_keys_json.html#__type.appliedRole\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":410,\"kind\":1024,\"name\":\"appliedRoleInput\",\"url\":\"modules/routes_form_keys_json.html#__type.appliedRoleInput\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":411,\"kind\":1024,\"name\":\"bestSkill\",\"url\":\"modules/routes_form_keys_json.html#__type.bestSkill\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":412,\"kind\":1024,\"name\":\"alumni\",\"url\":\"modules/routes_form_keys_json.html#__type.alumni\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":413,\"kind\":1024,\"name\":\"studentCoach\",\"url\":\"modules/routes_form_keys_json.html#__type.studentCoach\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/form_keys.json.__type\"},{\"id\":414,\"kind\":2,\"name\":\"routes/github\",\"url\":\"modules/routes_github.html\",\"classes\":\"tsd-kind-module\"},{\"id\":415,\"kind\":64,\"name\":\"getHome\",\"url\":\"modules/routes_github.html#getHome\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":416,\"kind\":64,\"name\":\"genState\",\"url\":\"modules/routes_github.html#genState\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":417,\"kind\":64,\"name\":\"checkState\",\"url\":\"modules/routes_github.html#checkState\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":418,\"kind\":64,\"name\":\"ghIdentity\",\"url\":\"modules/routes_github.html#ghIdentity\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":419,\"kind\":64,\"name\":\"ghExchangeAccessToken\",\"url\":\"modules/routes_github.html#ghExchangeAccessToken\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":420,\"kind\":64,\"name\":\"parseGHLogin\",\"url\":\"modules/routes_github.html#parseGHLogin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":421,\"kind\":64,\"name\":\"githubNameChange\",\"url\":\"modules/routes_github.html#githubNameChange\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":422,\"kind\":64,\"name\":\"ghSignupOrLogin\",\"url\":\"modules/routes_github.html#ghSignupOrLogin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":423,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_github.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":424,\"kind\":32,\"name\":\"states\",\"url\":\"modules/routes_github.html#states\",\"classes\":\"tsd-kind-variable tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":425,\"kind\":2,\"name\":\"routes/login\",\"url\":\"modules/routes_login.html\",\"classes\":\"tsd-kind-module\"},{\"id\":426,\"kind\":64,\"name\":\"login\",\"url\":\"modules/routes_login.html#login\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/login\"},{\"id\":427,\"kind\":64,\"name\":\"logout\",\"url\":\"modules/routes_login.html#logout\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/login\"},{\"id\":428,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_login.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/login\"},{\"id\":429,\"kind\":2,\"name\":\"routes/project\",\"url\":\"modules/routes_project.html\",\"classes\":\"tsd-kind-module\"},{\"id\":430,\"kind\":64,\"name\":\"createProject\",\"url\":\"modules/routes_project.html#createProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":431,\"kind\":64,\"name\":\"listProjects\",\"url\":\"modules/routes_project.html#listProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":432,\"kind\":64,\"name\":\"getProject\",\"url\":\"modules/routes_project.html#getProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":433,\"kind\":64,\"name\":\"modProject\",\"url\":\"modules/routes_project.html#modProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":434,\"kind\":64,\"name\":\"deleteProject\",\"url\":\"modules/routes_project.html#deleteProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":435,\"kind\":64,\"name\":\"getDraftedStudents\",\"url\":\"modules/routes_project.html#getDraftedStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":436,\"kind\":64,\"name\":\"getFreeSpotsFor\",\"url\":\"modules/routes_project.html#getFreeSpotsFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":437,\"kind\":64,\"name\":\"createProjectRoleFor\",\"url\":\"modules/routes_project.html#createProjectRoleFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":438,\"kind\":64,\"name\":\"modProjectStudent\",\"url\":\"modules/routes_project.html#modProjectStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":439,\"kind\":64,\"name\":\"unAssignStudent\",\"url\":\"modules/routes_project.html#unAssignStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":440,\"kind\":64,\"name\":\"getProjectConflicts\",\"url\":\"modules/routes_project.html#getProjectConflicts\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":441,\"kind\":64,\"name\":\"filterProjects\",\"url\":\"modules/routes_project.html#filterProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":442,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_project.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":443,\"kind\":2,\"name\":\"routes/reset\",\"url\":\"modules/routes_reset.html\",\"classes\":\"tsd-kind-module\"},{\"id\":444,\"kind\":64,\"name\":\"sendMail\",\"url\":\"modules/routes_reset.html#sendMail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":445,\"kind\":64,\"name\":\"requestReset\",\"url\":\"modules/routes_reset.html#requestReset\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":446,\"kind\":64,\"name\":\"checkCode\",\"url\":\"modules/routes_reset.html#checkCode\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":447,\"kind\":64,\"name\":\"resetPassword\",\"url\":\"modules/routes_reset.html#resetPassword\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":448,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_reset.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":449,\"kind\":64,\"name\":\"createEmail\",\"url\":\"modules/routes_reset.html#createEmail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":450,\"kind\":2,\"name\":\"routes/role\",\"url\":\"modules/routes_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":451,\"kind\":64,\"name\":\"listStudentRoles\",\"url\":\"modules/routes_role.html#listStudentRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/role\"},{\"id\":452,\"kind\":64,\"name\":\"createStudentRole\",\"url\":\"modules/routes_role.html#createStudentRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/role\"},{\"id\":453,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_role.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/role\"},{\"id\":454,\"kind\":2,\"name\":\"routes/session_key.json\",\"url\":\"modules/routes_session_key_json.html\",\"classes\":\"tsd-kind-module\"},{\"id\":455,\"kind\":1024,\"name\":\"export=\",\"url\":\"modules/routes_session_key_json.html#export_\",\"classes\":\"tsd-kind-property tsd-parent-kind-module\",\"parent\":\"routes/session_key.json\"},{\"id\":456,\"kind\":65536,\"name\":\"__type\",\"url\":\"modules/routes_session_key_json.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-module\",\"parent\":\"routes/session_key.json\"},{\"id\":457,\"kind\":1024,\"name\":\"valid_period\",\"url\":\"modules/routes_session_key_json.html#__type.valid_period\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"routes/session_key.json.__type\"},{\"id\":458,\"kind\":2,\"name\":\"routes/student\",\"url\":\"modules/routes_student.html\",\"classes\":\"tsd-kind-module\"},{\"id\":459,\"kind\":64,\"name\":\"listStudents\",\"url\":\"modules/routes_student.html#listStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":460,\"kind\":64,\"name\":\"getStudent\",\"url\":\"modules/routes_student.html#getStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":461,\"kind\":64,\"name\":\"deleteStudent\",\"url\":\"modules/routes_student.html#deleteStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":462,\"kind\":64,\"name\":\"createStudentSuggestion\",\"url\":\"modules/routes_student.html#createStudentSuggestion\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":463,\"kind\":64,\"name\":\"getStudentSuggestions\",\"url\":\"modules/routes_student.html#getStudentSuggestions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":464,\"kind\":64,\"name\":\"createStudentConfirmation\",\"url\":\"modules/routes_student.html#createStudentConfirmation\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":465,\"kind\":64,\"name\":\"filterStudents\",\"url\":\"modules/routes_student.html#filterStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":466,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_student.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":467,\"kind\":2,\"name\":\"routes/template\",\"url\":\"modules/routes_template.html\",\"classes\":\"tsd-kind-module\"},{\"id\":468,\"kind\":64,\"name\":\"getAllTemplates\",\"url\":\"modules/routes_template.html#getAllTemplates\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":469,\"kind\":64,\"name\":\"getSingleTemplate\",\"url\":\"modules/routes_template.html#getSingleTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":470,\"kind\":64,\"name\":\"createTemplate\",\"url\":\"modules/routes_template.html#createTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":471,\"kind\":64,\"name\":\"updateTemplate\",\"url\":\"modules/routes_template.html#updateTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":472,\"kind\":64,\"name\":\"deleteTemplate\",\"url\":\"modules/routes_template.html#deleteTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":473,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_template.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":474,\"kind\":2,\"name\":\"routes/user\",\"url\":\"modules/routes_user.html\",\"classes\":\"tsd-kind-module\"},{\"id\":475,\"kind\":64,\"name\":\"listUsers\",\"url\":\"modules/routes_user.html#listUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":476,\"kind\":64,\"name\":\"createUserRequest\",\"url\":\"modules/routes_user.html#createUserRequest\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":477,\"kind\":64,\"name\":\"setAccountStatus\",\"url\":\"modules/routes_user.html#setAccountStatus\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":478,\"kind\":64,\"name\":\"createUserAcceptance\",\"url\":\"modules/routes_user.html#createUserAcceptance\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":479,\"kind\":64,\"name\":\"deleteUserRequest\",\"url\":\"modules/routes_user.html#deleteUserRequest\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":480,\"kind\":64,\"name\":\"filterUsers\",\"url\":\"modules/routes_user.html#filterUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":481,\"kind\":64,\"name\":\"userModSelf\",\"url\":\"modules/routes_user.html#userModSelf\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":482,\"kind\":64,\"name\":\"getCurrentUser\",\"url\":\"modules/routes_user.html#getCurrentUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":483,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_user.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":484,\"kind\":2,\"name\":\"routes/verify\",\"url\":\"modules/routes_verify.html\",\"classes\":\"tsd-kind-module\"},{\"id\":485,\"kind\":64,\"name\":\"verifyKey\",\"url\":\"modules/routes_verify.html#verifyKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/verify\"},{\"id\":486,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_verify.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/verify\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"parent\"],\"fieldVectors\":[[\"name/0\",[0,46.862]],[\"parent/0\",[]],[\"name/1\",[1,52.74]],[\"parent/1\",[0,4.542]],[\"name/2\",[2,57.849]],[\"parent/2\",[0,4.542]],[\"name/3\",[3,57.849]],[\"parent/3\",[0,4.542]],[\"name/4\",[4,44.856]],[\"parent/4\",[]],[\"name/5\",[5,57.849]],[\"parent/5\",[4,4.348]],[\"name/6\",[6,57.849]],[\"parent/6\",[4,4.348]],[\"name/7\",[7,57.849]],[\"parent/7\",[4,4.348]],[\"name/8\",[8,57.849]],[\"parent/8\",[4,4.348]],[\"name/9\",[9,40.502]],[\"parent/9\",[]],[\"name/10\",[10,52.74]],[\"parent/10\",[9,3.926]],[\"name/11\",[11,52.74]],[\"parent/11\",[9,3.926]],[\"name/12\",[12,57.849]],[\"parent/12\",[9,3.926]],[\"name/13\",[13,57.849]],[\"parent/13\",[9,3.926]],[\"name/14\",[14,57.849]],[\"parent/14\",[9,3.926]],[\"name/15\",[15,57.849]],[\"parent/15\",[9,3.926]],[\"name/16\",[16,57.849]],[\"parent/16\",[9,3.926]],[\"name/17\",[17,41.754]],[\"parent/17\",[]],[\"name/18\",[18,57.849]],[\"parent/18\",[17,4.047]],[\"name/19\",[19,52.74]],[\"parent/19\",[17,4.047]],[\"name/20\",[20,52.74]],[\"parent/20\",[17,4.047]],[\"name/21\",[21,57.849]],[\"parent/21\",[17,4.047]],[\"name/22\",[22,57.849]],[\"parent/22\",[17,4.047]],[\"name/23\",[23,57.849]],[\"parent/23\",[17,4.047]],[\"name/24\",[24,52.74]],[\"parent/24\",[]],[\"name/25\",[25,52.74]],[\"parent/25\",[24,5.112]],[\"name/26\",[26,36.646]],[\"parent/26\",[]],[\"name/27\",[27,57.849]],[\"parent/27\",[26,3.552]],[\"name/28\",[28,57.849]],[\"parent/28\",[26,3.552]],[\"name/29\",[29,57.849]],[\"parent/29\",[26,3.552]],[\"name/30\",[30,57.849]],[\"parent/30\",[26,3.552]],[\"name/31\",[31,57.849]],[\"parent/31\",[26,3.552]],[\"name/32\",[32,57.849]],[\"parent/32\",[26,3.552]],[\"name/33\",[33,57.849]],[\"parent/33\",[26,3.552]],[\"name/34\",[34,52.74]],[\"parent/34\",[26,3.552]],[\"name/35\",[35,57.849]],[\"parent/35\",[26,3.552]],[\"name/36\",[36,57.849]],[\"parent/36\",[26,3.552]],[\"name/37\",[37,57.849]],[\"parent/37\",[26,3.552]],[\"name/38\",[38,40.502]],[\"parent/38\",[]],[\"name/39\",[39,52.74]],[\"parent/39\",[38,3.926]],[\"name/40\",[40,57.849]],[\"parent/40\",[38,3.926]],[\"name/41\",[41,57.849]],[\"parent/41\",[38,3.926]],[\"name/42\",[42,57.849]],[\"parent/42\",[38,3.926]],[\"name/43\",[43,52.74]],[\"parent/43\",[38,3.926]],[\"name/44\",[44,57.849]],[\"parent/44\",[38,3.926]],[\"name/45\",[45,57.849]],[\"parent/45\",[38,3.926]],[\"name/46\",[46,40.502]],[\"parent/46\",[]],[\"name/47\",[47,57.849]],[\"parent/47\",[46,3.926]],[\"name/48\",[48,57.849]],[\"parent/48\",[46,3.926]],[\"name/49\",[49,57.849]],[\"parent/49\",[46,3.926]],[\"name/50\",[50,57.849]],[\"parent/50\",[46,3.926]],[\"name/51\",[51,52.74]],[\"parent/51\",[46,3.926]],[\"name/52\",[52,57.849]],[\"parent/52\",[46,3.926]],[\"name/53\",[53,57.849]],[\"parent/53\",[46,3.926]],[\"name/54\",[54,33.87]],[\"parent/54\",[]],[\"name/55\",[55,52.74]],[\"parent/55\",[54,3.283]],[\"name/56\",[56,57.849]],[\"parent/56\",[54,3.283]],[\"name/57\",[57,57.849]],[\"parent/57\",[54,3.283]],[\"name/58\",[58,57.849]],[\"parent/58\",[54,3.283]],[\"name/59\",[59,57.849]],[\"parent/59\",[54,3.283]],[\"name/60\",[60,57.849]],[\"parent/60\",[54,3.283]],[\"name/61\",[61,57.849]],[\"parent/61\",[54,3.283]],[\"name/62\",[62,57.849]],[\"parent/62\",[54,3.283]],[\"name/63\",[63,52.74]],[\"parent/63\",[54,3.283]],[\"name/64\",[64,57.849]],[\"parent/64\",[54,3.283]],[\"name/65\",[65,57.849]],[\"parent/65\",[54,3.283]],[\"name/66\",[66,57.849]],[\"parent/66\",[54,3.283]],[\"name/67\",[67,57.849]],[\"parent/67\",[54,3.283]],[\"name/68\",[68,57.849]],[\"parent/68\",[54,3.283]],[\"name/69\",[69,57.849]],[\"parent/69\",[54,3.283]],[\"name/70\",[70,27.091]],[\"parent/70\",[]],[\"name/71\",[71,52.74]],[\"parent/71\",[70,2.626]],[\"name/72\",[72,52.74]],[\"parent/72\",[73,4.348]],[\"name/73\",[74,49.376]],[\"parent/73\",[73,4.348]],[\"name/74\",[75,52.74]],[\"parent/74\",[73,4.348]],[\"name/75\",[76,52.74]],[\"parent/75\",[73,4.348]],[\"name/76\",[77,57.849]],[\"parent/76\",[73,4.348]],[\"name/77\",[78,52.74]],[\"parent/77\",[70,2.626]],[\"name/78\",[79,49.376]],[\"parent/78\",[80,4.348]],[\"name/79\",[72,52.74]],[\"parent/79\",[80,4.348]],[\"name/80\",[74,49.376]],[\"parent/80\",[80,4.348]],[\"name/81\",[75,52.74]],[\"parent/81\",[80,4.348]],[\"name/82\",[76,52.74]],[\"parent/82\",[80,4.348]],[\"name/83\",[55,52.74]],[\"parent/83\",[70,2.626]],[\"name/84\",[79,49.376]],[\"parent/84\",[81,4.348]],[\"name/85\",[82,52.74]],[\"parent/85\",[81,4.348]],[\"name/86\",[83,52.74]],[\"parent/86\",[81,4.348]],[\"name/87\",[84,52.74]],[\"parent/87\",[81,4.348]],[\"name/88\",[85,52.74]],[\"parent/88\",[81,4.348]],[\"name/89\",[63,52.74]],[\"parent/89\",[70,2.626]],[\"name/90\",[86,41.754]],[\"parent/90\",[87,4.348]],[\"name/91\",[82,52.74]],[\"parent/91\",[87,4.348]],[\"name/92\",[83,52.74]],[\"parent/92\",[87,4.348]],[\"name/93\",[84,52.74]],[\"parent/93\",[87,4.348]],[\"name/94\",[85,52.74]],[\"parent/94\",[87,4.348]],[\"name/95\",[88,52.74]],[\"parent/95\",[70,2.626]],[\"name/96\",[79,49.376]],[\"parent/96\",[89,4.186]],[\"name/97\",[90,49.376]],[\"parent/97\",[89,4.186]],[\"name/98\",[91,52.74]],[\"parent/98\",[89,4.186]],[\"name/99\",[92,49.376]],[\"parent/99\",[89,4.186]],[\"name/100\",[93,49.376]],[\"parent/100\",[89,4.186]],[\"name/101\",[94,49.376]],[\"parent/101\",[89,4.186]],[\"name/102\",[95,52.74]],[\"parent/102\",[70,2.626]],[\"name/103\",[96,46.862]],[\"parent/103\",[97,4.186]],[\"name/104\",[90,49.376]],[\"parent/104\",[97,4.186]],[\"name/105\",[91,52.74]],[\"parent/105\",[97,4.186]],[\"name/106\",[92,49.376]],[\"parent/106\",[97,4.186]],[\"name/107\",[93,49.376]],[\"parent/107\",[97,4.186]],[\"name/108\",[94,49.376]],[\"parent/108\",[97,4.186]],[\"name/109\",[19,52.74]],[\"parent/109\",[70,2.626]],[\"name/110\",[86,41.754]],[\"parent/110\",[98,4.348]],[\"name/111\",[99,46.862]],[\"parent/111\",[98,4.348]],[\"name/112\",[100,52.74]],[\"parent/112\",[98,4.348]],[\"name/113\",[101,52.74]],[\"parent/113\",[98,4.348]],[\"name/114\",[102,57.849]],[\"parent/114\",[98,4.348]],[\"name/115\",[20,52.74]],[\"parent/115\",[70,2.626]],[\"name/116\",[103,57.849]],[\"parent/116\",[104,4.542]],[\"name/117\",[86,41.754]],[\"parent/117\",[104,4.542]],[\"name/118\",[100,52.74]],[\"parent/118\",[104,4.542]],[\"name/119\",[101,52.74]],[\"parent/119\",[104,4.542]],[\"name/120\",[10,52.74]],[\"parent/120\",[70,2.626]],[\"name/121\",[96,46.862]],[\"parent/121\",[105,4.348]],[\"name/122\",[106,49.376]],[\"parent/122\",[105,4.348]],[\"name/123\",[107,49.376]],[\"parent/123\",[105,4.348]],[\"name/124\",[86,41.754]],[\"parent/124\",[105,4.348]],[\"name/125\",[108,52.74]],[\"parent/125\",[105,4.348]],[\"name/126\",[11,52.74]],[\"parent/126\",[70,2.626]],[\"name/127\",[109,57.849]],[\"parent/127\",[110,4.348]],[\"name/128\",[86,41.754]],[\"parent/128\",[110,4.348]],[\"name/129\",[107,49.376]],[\"parent/129\",[110,4.348]],[\"name/130\",[108,52.74]],[\"parent/130\",[110,4.348]],[\"name/131\",[106,49.376]],[\"parent/131\",[110,4.348]],[\"name/132\",[34,52.74]],[\"parent/132\",[70,2.626]],[\"name/133\",[96,46.862]],[\"parent/133\",[111,3.477]],[\"name/134\",[112,52.74]],[\"parent/134\",[111,3.477]],[\"name/135\",[113,52.74]],[\"parent/135\",[111,3.477]],[\"name/136\",[114,57.849]],[\"parent/136\",[111,3.477]],[\"name/137\",[115,52.74]],[\"parent/137\",[111,3.477]],[\"name/138\",[116,46.862]],[\"parent/138\",[111,3.477]],[\"name/139\",[117,52.74]],[\"parent/139\",[111,3.477]],[\"name/140\",[118,52.74]],[\"parent/140\",[111,3.477]],[\"name/141\",[119,52.74]],[\"parent/141\",[111,3.477]],[\"name/142\",[120,52.74]],[\"parent/142\",[111,3.477]],[\"name/143\",[121,52.74]],[\"parent/143\",[111,3.477]],[\"name/144\",[122,57.849]],[\"parent/144\",[111,3.477]],[\"name/145\",[123,57.849]],[\"parent/145\",[111,3.477]],[\"name/146\",[124,52.74]],[\"parent/146\",[70,2.626]],[\"name/147\",[116,46.862]],[\"parent/147\",[125,5.112]],[\"name/148\",[126,57.849]],[\"parent/148\",[125,5.112]],[\"name/149\",[127,49.376]],[\"parent/149\",[70,2.626]],[\"name/150\",[128,43.185]],[\"parent/150\",[129,4.186]],[\"name/151\",[116,46.862]],[\"parent/151\",[129,4.186]],[\"name/152\",[130,52.74]],[\"parent/152\",[129,4.186]],[\"name/153\",[131,52.74]],[\"parent/153\",[129,4.186]],[\"name/154\",[132,52.74]],[\"parent/154\",[129,4.186]],[\"name/155\",[133,46.862]],[\"parent/155\",[129,4.186]],[\"name/156\",[134,52.74]],[\"parent/156\",[70,2.626]],[\"name/157\",[135,44.856]],[\"parent/157\",[136,4.047]],[\"name/158\",[128,43.185]],[\"parent/158\",[136,4.047]],[\"name/159\",[116,46.862]],[\"parent/159\",[136,4.047]],[\"name/160\",[130,52.74]],[\"parent/160\",[136,4.047]],[\"name/161\",[131,52.74]],[\"parent/161\",[136,4.047]],[\"name/162\",[132,52.74]],[\"parent/162\",[136,4.047]],[\"name/163\",[133,46.862]],[\"parent/163\",[136,4.047]],[\"name/164\",[137,52.74]],[\"parent/164\",[70,2.626]],[\"name/165\",[135,44.856]],[\"parent/165\",[138,4.786]],[\"name/166\",[139,46.862]],[\"parent/166\",[138,4.786]],[\"name/167\",[133,46.862]],[\"parent/167\",[138,4.786]],[\"name/168\",[140,52.74]],[\"parent/168\",[70,2.626]],[\"name/169\",[106,49.376]],[\"parent/169\",[141,4.542]],[\"name/170\",[135,44.856]],[\"parent/170\",[141,4.542]],[\"name/171\",[139,46.862]],[\"parent/171\",[141,4.542]],[\"name/172\",[133,46.862]],[\"parent/172\",[141,4.542]],[\"name/173\",[142,52.74]],[\"parent/173\",[70,2.626]],[\"name/174\",[139,46.862]],[\"parent/174\",[143,5.112]],[\"name/175\",[128,43.185]],[\"parent/175\",[143,5.112]],[\"name/176\",[51,52.74]],[\"parent/176\",[70,2.626]],[\"name/177\",[144,49.376]],[\"parent/177\",[145,5.112]],[\"name/178\",[128,43.185]],[\"parent/178\",[145,5.112]],[\"name/179\",[39,52.74]],[\"parent/179\",[70,2.626]],[\"name/180\",[99,46.862]],[\"parent/180\",[146,4.186]],[\"name/181\",[147,52.74]],[\"parent/181\",[146,4.186]],[\"name/182\",[144,49.376]],[\"parent/182\",[146,4.186]],[\"name/183\",[148,52.74]],[\"parent/183\",[146,4.186]],[\"name/184\",[149,52.74]],[\"parent/184\",[146,4.186]],[\"name/185\",[150,57.849]],[\"parent/185\",[146,4.186]],[\"name/186\",[43,52.74]],[\"parent/186\",[70,2.626]],[\"name/187\",[151,57.849]],[\"parent/187\",[152,4.047]],[\"name/188\",[99,46.862]],[\"parent/188\",[152,4.047]],[\"name/189\",[147,52.74]],[\"parent/189\",[152,4.047]],[\"name/190\",[144,49.376]],[\"parent/190\",[152,4.047]],[\"name/191\",[148,52.74]],[\"parent/191\",[152,4.047]],[\"name/192\",[149,52.74]],[\"parent/192\",[152,4.047]],[\"name/193\",[153,57.849]],[\"parent/193\",[152,4.047]],[\"name/194\",[25,52.74]],[\"parent/194\",[70,2.626]],[\"name/195\",[86,41.754]],[\"parent/195\",[154,4.348]],[\"name/196\",[96,46.862]],[\"parent/196\",[154,4.348]],[\"name/197\",[135,44.856]],[\"parent/197\",[154,4.348]],[\"name/198\",[155,57.849]],[\"parent/198\",[154,4.348]],[\"name/199\",[107,49.376]],[\"parent/199\",[154,4.348]],[\"name/200\",[156,52.74]],[\"parent/200\",[70,2.626]],[\"name/201\",[135,44.856]],[\"parent/201\",[157,5.112]],[\"name/202\",[86,41.754]],[\"parent/202\",[157,5.112]],[\"name/203\",[1,52.74]],[\"parent/203\",[70,2.626]],[\"name/204\",[99,46.862]],[\"parent/204\",[158,5.112]],[\"name/205\",[139,46.862]],[\"parent/205\",[158,5.112]],[\"name/206\",[159,49.376]],[\"parent/206\",[70,2.626]],[\"name/207\",[160,52.74]],[\"parent/207\",[161,4.348]],[\"name/208\",[128,43.185]],[\"parent/208\",[161,4.348]],[\"name/209\",[162,52.74]],[\"parent/209\",[161,4.348]],[\"name/210\",[163,52.74]],[\"parent/210\",[161,4.348]],[\"name/211\",[164,52.74]],[\"parent/211\",[161,4.348]],[\"name/212\",[165,49.376]],[\"parent/212\",[70,2.626]],[\"name/213\",[166,57.849]],[\"parent/213\",[167,4.186]],[\"name/214\",[160,52.74]],[\"parent/214\",[167,4.186]],[\"name/215\",[128,43.185]],[\"parent/215\",[167,4.186]],[\"name/216\",[162,52.74]],[\"parent/216\",[167,4.186]],[\"name/217\",[163,52.74]],[\"parent/217\",[167,4.186]],[\"name/218\",[164,52.74]],[\"parent/218\",[167,4.186]],[\"name/219\",[168,57.849]],[\"parent/219\",[70,2.626]],[\"name/220\",[169,57.849]],[\"parent/220\",[70,2.626]],[\"name/221\",[170,57.849]],[\"parent/221\",[70,2.626]],[\"name/222\",[171,57.849]],[\"parent/222\",[70,2.626]],[\"name/223\",[172,57.849]],[\"parent/223\",[70,2.626]],[\"name/224\",[173,57.849]],[\"parent/224\",[70,2.626]],[\"name/225\",[174,35.876]],[\"parent/225\",[]],[\"name/226\",[175,57.849]],[\"parent/226\",[174,3.477]],[\"name/227\",[176,57.849]],[\"parent/227\",[174,3.477]],[\"name/228\",[177,57.849]],[\"parent/228\",[174,3.477]],[\"name/229\",[178,57.849]],[\"parent/229\",[174,3.477]],[\"name/230\",[179,57.849]],[\"parent/230\",[174,3.477]],[\"name/231\",[180,57.849]],[\"parent/231\",[174,3.477]],[\"name/232\",[124,52.74]],[\"parent/232\",[174,3.477]],[\"name/233\",[181,57.849]],[\"parent/233\",[174,3.477]],[\"name/234\",[182,57.849]],[\"parent/234\",[174,3.477]],[\"name/235\",[183,57.849]],[\"parent/235\",[174,3.477]],[\"name/236\",[184,57.849]],[\"parent/236\",[174,3.477]],[\"name/237\",[185,57.849]],[\"parent/237\",[174,3.477]],[\"name/238\",[186,44.856]],[\"parent/238\",[]],[\"name/239\",[187,57.849]],[\"parent/239\",[186,4.348]],[\"name/240\",[188,57.849]],[\"parent/240\",[186,4.348]],[\"name/241\",[189,57.849]],[\"parent/241\",[186,4.348]],[\"name/242\",[190,57.849]],[\"parent/242\",[186,4.348]],[\"name/243\",[191,39.39]],[\"parent/243\",[]],[\"name/244\",[71,52.74]],[\"parent/244\",[191,3.818]],[\"name/245\",[192,57.849]],[\"parent/245\",[191,3.818]],[\"name/246\",[193,57.849]],[\"parent/246\",[191,3.818]],[\"name/247\",[194,57.849]],[\"parent/247\",[191,3.818]],[\"name/248\",[195,57.849]],[\"parent/248\",[191,3.818]],[\"name/249\",[196,57.849]],[\"parent/249\",[191,3.818]],[\"name/250\",[78,52.74]],[\"parent/250\",[191,3.818]],[\"name/251\",[197,57.849]],[\"parent/251\",[191,3.818]],[\"name/252\",[198,31.223]],[\"parent/252\",[]],[\"name/253\",[127,49.376]],[\"parent/253\",[198,3.026]],[\"name/254\",[199,57.849]],[\"parent/254\",[198,3.026]],[\"name/255\",[200,57.849]],[\"parent/255\",[198,3.026]],[\"name/256\",[201,57.849]],[\"parent/256\",[198,3.026]],[\"name/257\",[202,57.849]],[\"parent/257\",[198,3.026]],[\"name/258\",[203,57.849]],[\"parent/258\",[198,3.026]],[\"name/259\",[204,57.849]],[\"parent/259\",[198,3.026]],[\"name/260\",[205,57.849]],[\"parent/260\",[198,3.026]],[\"name/261\",[206,57.849]],[\"parent/261\",[198,3.026]],[\"name/262\",[207,57.849]],[\"parent/262\",[198,3.026]],[\"name/263\",[208,57.849]],[\"parent/263\",[198,3.026]],[\"name/264\",[209,57.849]],[\"parent/264\",[198,3.026]],[\"name/265\",[210,57.849]],[\"parent/265\",[198,3.026]],[\"name/266\",[211,57.849]],[\"parent/266\",[198,3.026]],[\"name/267\",[212,57.849]],[\"parent/267\",[198,3.026]],[\"name/268\",[134,52.74]],[\"parent/268\",[198,3.026]],[\"name/269\",[213,52.74]],[\"parent/269\",[198,3.026]],[\"name/270\",[214,57.849]],[\"parent/270\",[198,3.026]],[\"name/271\",[215,57.849]],[\"parent/271\",[198,3.026]],[\"name/272\",[216,52.74]],[\"parent/272\",[198,3.026]],[\"name/273\",[217,39.39]],[\"parent/273\",[]],[\"name/274\",[137,52.74]],[\"parent/274\",[217,3.818]],[\"name/275\",[218,57.849]],[\"parent/275\",[217,3.818]],[\"name/276\",[219,57.849]],[\"parent/276\",[217,3.818]],[\"name/277\",[220,57.849]],[\"parent/277\",[217,3.818]],[\"name/278\",[140,52.74]],[\"parent/278\",[217,3.818]],[\"name/279\",[221,57.849]],[\"parent/279\",[217,3.818]],[\"name/280\",[222,57.849]],[\"parent/280\",[217,3.818]],[\"name/281\",[223,57.849]],[\"parent/281\",[217,3.818]],[\"name/282\",[224,49.376]],[\"parent/282\",[]],[\"name/283\",[156,52.74]],[\"parent/283\",[224,4.786]],[\"name/284\",[225,57.849]],[\"parent/284\",[224,4.786]],[\"name/285\",[226,39.39]],[\"parent/285\",[]],[\"name/286\",[227,57.849]],[\"parent/286\",[226,3.818]],[\"name/287\",[228,57.849]],[\"parent/287\",[226,3.818]],[\"name/288\",[229,57.849]],[\"parent/288\",[226,3.818]],[\"name/289\",[230,57.849]],[\"parent/289\",[226,3.818]],[\"name/290\",[231,57.849]],[\"parent/290\",[226,3.818]],[\"name/291\",[142,52.74]],[\"parent/291\",[226,3.818]],[\"name/292\",[232,57.849]],[\"parent/292\",[226,3.818]],[\"name/293\",[233,57.849]],[\"parent/293\",[226,3.818]],[\"name/294\",[234,43.185]],[\"parent/294\",[]],[\"name/295\",[235,57.849]],[\"parent/295\",[234,4.186]],[\"name/296\",[236,57.849]],[\"parent/296\",[234,4.186]],[\"name/297\",[237,57.849]],[\"parent/297\",[234,4.186]],[\"name/298\",[238,57.849]],[\"parent/298\",[234,4.186]],[\"name/299\",[239,57.849]],[\"parent/299\",[234,4.186]],[\"name/300\",[240,40.502]],[\"parent/300\",[]],[\"name/301\",[88,52.74]],[\"parent/301\",[240,3.926]],[\"name/302\",[241,57.849]],[\"parent/302\",[240,3.926]],[\"name/303\",[242,52.74]],[\"parent/303\",[240,3.926]],[\"name/304\",[95,52.74]],[\"parent/304\",[240,3.926]],[\"name/305\",[243,52.74]],[\"parent/305\",[240,3.926]],[\"name/306\",[244,57.849]],[\"parent/306\",[240,3.926]],[\"name/307\",[245,52.74]],[\"parent/307\",[240,3.926]],[\"name/308\",[246,41.754]],[\"parent/308\",[]],[\"name/309\",[247,52.74]],[\"parent/309\",[246,4.047]],[\"name/310\",[248,57.849]],[\"parent/310\",[246,4.047]],[\"name/311\",[249,57.849]],[\"parent/311\",[246,4.047]],[\"name/312\",[159,49.376]],[\"parent/312\",[246,4.047]],[\"name/313\",[165,49.376]],[\"parent/313\",[246,4.047]],[\"name/314\",[250,52.74]],[\"parent/314\",[246,4.047]],[\"name/315\",[251,44.856]],[\"parent/315\",[]],[\"name/316\",[252,57.849]],[\"parent/316\",[251,4.348]],[\"name/317\",[253,57.849]],[\"parent/317\",[251,4.348]],[\"name/318\",[254,57.849]],[\"parent/318\",[251,4.348]],[\"name/319\",[255,35.876]],[\"parent/319\",[251,4.348]],[\"name/320\",[256,43.185]],[\"parent/320\",[]],[\"name/321\",[257,57.849]],[\"parent/321\",[256,4.186]],[\"name/322\",[258,57.849]],[\"parent/322\",[256,4.186]],[\"name/323\",[259,57.849]],[\"parent/323\",[256,4.186]],[\"name/324\",[260,57.849]],[\"parent/324\",[256,4.186]],[\"name/325\",[255,35.876]],[\"parent/325\",[256,4.186]],[\"name/326\",[261,44.856]],[\"parent/326\",[]],[\"name/327\",[262,57.849]],[\"parent/327\",[261,4.348]],[\"name/328\",[263,57.849]],[\"parent/328\",[261,4.348]],[\"name/329\",[264,57.849]],[\"parent/329\",[261,4.348]],[\"name/330\",[255,35.876]],[\"parent/330\",[261,4.348]],[\"name/331\",[265,24.176]],[\"parent/331\",[]],[\"name/332\",[266,57.849]],[\"parent/332\",[265,2.343]],[\"name/333\",[267,57.849]],[\"parent/333\",[265,2.343]],[\"name/334\",[268,57.849]],[\"parent/334\",[265,2.343]],[\"name/335\",[269,57.849]],[\"parent/335\",[265,2.343]],[\"name/336\",[270,57.849]],[\"parent/336\",[265,2.343]],[\"name/337\",[271,57.849]],[\"parent/337\",[265,2.343]],[\"name/338\",[272,57.849]],[\"parent/338\",[265,2.343]],[\"name/339\",[273,57.849]],[\"parent/339\",[265,2.343]],[\"name/340\",[274,57.849]],[\"parent/340\",[265,2.343]],[\"name/341\",[275,57.849]],[\"parent/341\",[265,2.343]],[\"name/342\",[276,57.849]],[\"parent/342\",[265,2.343]],[\"name/343\",[277,57.849]],[\"parent/343\",[265,2.343]],[\"name/344\",[278,57.849]],[\"parent/344\",[265,2.343]],[\"name/345\",[279,57.849]],[\"parent/345\",[265,2.343]],[\"name/346\",[280,57.849]],[\"parent/346\",[265,2.343]],[\"name/347\",[281,57.849]],[\"parent/347\",[265,2.343]],[\"name/348\",[282,57.849]],[\"parent/348\",[265,2.343]],[\"name/349\",[283,57.849]],[\"parent/349\",[265,2.343]],[\"name/350\",[284,57.849]],[\"parent/350\",[265,2.343]],[\"name/351\",[285,57.849]],[\"parent/351\",[265,2.343]],[\"name/352\",[286,57.849]],[\"parent/352\",[265,2.343]],[\"name/353\",[287,57.849]],[\"parent/353\",[265,2.343]],[\"name/354\",[288,57.849]],[\"parent/354\",[265,2.343]],[\"name/355\",[289,57.849]],[\"parent/355\",[265,2.343]],[\"name/356\",[290,57.849]],[\"parent/356\",[265,2.343]],[\"name/357\",[291,57.849]],[\"parent/357\",[265,2.343]],[\"name/358\",[292,57.849]],[\"parent/358\",[265,2.343]],[\"name/359\",[293,57.849]],[\"parent/359\",[265,2.343]],[\"name/360\",[294,57.849]],[\"parent/360\",[265,2.343]],[\"name/361\",[295,57.849]],[\"parent/361\",[265,2.343]],[\"name/362\",[296,57.849]],[\"parent/362\",[265,2.343]],[\"name/363\",[297,57.849]],[\"parent/363\",[265,2.343]],[\"name/364\",[298,57.849]],[\"parent/364\",[265,2.343]],[\"name/365\",[299,57.849]],[\"parent/365\",[265,2.343]],[\"name/366\",[300,57.849]],[\"parent/366\",[265,2.343]],[\"name/367\",[301,57.849]],[\"parent/367\",[265,2.343]],[\"name/368\",[302,57.849]],[\"parent/368\",[265,2.343]],[\"name/369\",[303,57.849]],[\"parent/369\",[265,2.343]],[\"name/370\",[304,57.849]],[\"parent/370\",[265,2.343]],[\"name/371\",[305,57.849]],[\"parent/371\",[265,2.343]],[\"name/372\",[306,57.849]],[\"parent/372\",[265,2.343]],[\"name/373\",[255,35.876]],[\"parent/373\",[265,2.343]],[\"name/374\",[307,49.376]],[\"parent/374\",[]],[\"name/375\",[308,52.74]],[\"parent/375\",[307,4.786]],[\"name/376\",[309,52.74]],[\"parent/376\",[307,4.786]],[\"name/377\",[310,57.849]],[\"parent/377\",[311,2.487]],[\"name/378\",[312,57.849]],[\"parent/378\",[311,2.487]],[\"name/379\",[313,57.849]],[\"parent/379\",[311,2.487]],[\"name/380\",[112,52.74]],[\"parent/380\",[311,2.487]],[\"name/381\",[314,57.849]],[\"parent/381\",[311,2.487]],[\"name/382\",[74,49.376]],[\"parent/382\",[311,2.487]],[\"name/383\",[93,49.376]],[\"parent/383\",[311,2.487]],[\"name/384\",[315,57.849]],[\"parent/384\",[311,2.487]],[\"name/385\",[90,49.376]],[\"parent/385\",[311,2.487]],[\"name/386\",[316,57.849]],[\"parent/386\",[311,2.487]],[\"name/387\",[317,57.849]],[\"parent/387\",[311,2.487]],[\"name/388\",[318,57.849]],[\"parent/388\",[311,2.487]],[\"name/389\",[319,57.849]],[\"parent/389\",[311,2.487]],[\"name/390\",[320,57.849]],[\"parent/390\",[311,2.487]],[\"name/391\",[321,57.849]],[\"parent/391\",[311,2.487]],[\"name/392\",[92,49.376]],[\"parent/392\",[311,2.487]],[\"name/393\",[322,57.849]],[\"parent/393\",[311,2.487]],[\"name/394\",[323,57.849]],[\"parent/394\",[311,2.487]],[\"name/395\",[324,57.849]],[\"parent/395\",[311,2.487]],[\"name/396\",[325,57.849]],[\"parent/396\",[311,2.487]],[\"name/397\",[326,57.849]],[\"parent/397\",[311,2.487]],[\"name/398\",[327,57.849]],[\"parent/398\",[311,2.487]],[\"name/399\",[328,57.849]],[\"parent/399\",[311,2.487]],[\"name/400\",[329,57.849]],[\"parent/400\",[311,2.487]],[\"name/401\",[113,52.74]],[\"parent/401\",[311,2.487]],[\"name/402\",[117,52.74]],[\"parent/402\",[311,2.487]],[\"name/403\",[330,57.849]],[\"parent/403\",[311,2.487]],[\"name/404\",[118,52.74]],[\"parent/404\",[311,2.487]],[\"name/405\",[331,57.849]],[\"parent/405\",[311,2.487]],[\"name/406\",[119,52.74]],[\"parent/406\",[311,2.487]],[\"name/407\",[120,52.74]],[\"parent/407\",[311,2.487]],[\"name/408\",[121,52.74]],[\"parent/408\",[311,2.487]],[\"name/409\",[332,57.849]],[\"parent/409\",[311,2.487]],[\"name/410\",[333,57.849]],[\"parent/410\",[311,2.487]],[\"name/411\",[334,57.849]],[\"parent/411\",[311,2.487]],[\"name/412\",[94,49.376]],[\"parent/412\",[311,2.487]],[\"name/413\",[115,52.74]],[\"parent/413\",[311,2.487]],[\"name/414\",[335,37.48]],[\"parent/414\",[]],[\"name/415\",[336,57.849]],[\"parent/415\",[335,3.633]],[\"name/416\",[337,57.849]],[\"parent/416\",[335,3.633]],[\"name/417\",[338,57.849]],[\"parent/417\",[335,3.633]],[\"name/418\",[339,57.849]],[\"parent/418\",[335,3.633]],[\"name/419\",[340,57.849]],[\"parent/419\",[335,3.633]],[\"name/420\",[341,57.849]],[\"parent/420\",[335,3.633]],[\"name/421\",[342,57.849]],[\"parent/421\",[335,3.633]],[\"name/422\",[343,57.849]],[\"parent/422\",[335,3.633]],[\"name/423\",[255,35.876]],[\"parent/423\",[335,3.633]],[\"name/424\",[344,57.849]],[\"parent/424\",[335,3.633]],[\"name/425\",[345,46.862]],[\"parent/425\",[]],[\"name/426\",[346,57.849]],[\"parent/426\",[345,4.542]],[\"name/427\",[347,57.849]],[\"parent/427\",[345,4.542]],[\"name/428\",[255,35.876]],[\"parent/428\",[345,4.542]],[\"name/429\",[348,35.162]],[\"parent/429\",[]],[\"name/430\",[127,49.376]],[\"parent/430\",[348,3.408]],[\"name/431\",[349,57.849]],[\"parent/431\",[348,3.408]],[\"name/432\",[350,57.849]],[\"parent/432\",[348,3.408]],[\"name/433\",[351,57.849]],[\"parent/433\",[348,3.408]],[\"name/434\",[213,52.74]],[\"parent/434\",[348,3.408]],[\"name/435\",[352,57.849]],[\"parent/435\",[348,3.408]],[\"name/436\",[353,57.849]],[\"parent/436\",[348,3.408]],[\"name/437\",[354,57.849]],[\"parent/437\",[348,3.408]],[\"name/438\",[355,57.849]],[\"parent/438\",[348,3.408]],[\"name/439\",[356,57.849]],[\"parent/439\",[348,3.408]],[\"name/440\",[357,57.849]],[\"parent/440\",[348,3.408]],[\"name/441\",[216,52.74]],[\"parent/441\",[348,3.408]],[\"name/442\",[255,35.876]],[\"parent/442\",[348,3.408]],[\"name/443\",[358,41.754]],[\"parent/443\",[]],[\"name/444\",[359,57.849]],[\"parent/444\",[358,4.047]],[\"name/445\",[360,57.849]],[\"parent/445\",[358,4.047]],[\"name/446\",[361,57.849]],[\"parent/446\",[358,4.047]],[\"name/447\",[362,57.849]],[\"parent/447\",[358,4.047]],[\"name/448\",[255,35.876]],[\"parent/448\",[358,4.047]],[\"name/449\",[363,57.849]],[\"parent/449\",[358,4.047]],[\"name/450\",[364,46.862]],[\"parent/450\",[]],[\"name/451\",[365,57.849]],[\"parent/451\",[364,4.542]],[\"name/452\",[366,57.849]],[\"parent/452\",[364,4.542]],[\"name/453\",[255,35.876]],[\"parent/453\",[364,4.542]],[\"name/454\",[367,49.376]],[\"parent/454\",[]],[\"name/455\",[308,52.74]],[\"parent/455\",[367,4.786]],[\"name/456\",[309,52.74]],[\"parent/456\",[367,4.786]],[\"name/457\",[368,57.849]],[\"parent/457\",[369,5.607]],[\"name/458\",[370,39.39]],[\"parent/458\",[]],[\"name/459\",[371,57.849]],[\"parent/459\",[370,3.818]],[\"name/460\",[242,52.74]],[\"parent/460\",[370,3.818]],[\"name/461\",[243,52.74]],[\"parent/461\",[370,3.818]],[\"name/462\",[372,57.849]],[\"parent/462\",[370,3.818]],[\"name/463\",[373,57.849]],[\"parent/463\",[370,3.818]],[\"name/464\",[374,57.849]],[\"parent/464\",[370,3.818]],[\"name/465\",[245,52.74]],[\"parent/465\",[370,3.818]],[\"name/466\",[255,35.876]],[\"parent/466\",[370,3.818]],[\"name/467\",[375,41.754]],[\"parent/467\",[]],[\"name/468\",[247,52.74]],[\"parent/468\",[375,4.047]],[\"name/469\",[376,57.849]],[\"parent/469\",[375,4.047]],[\"name/470\",[159,49.376]],[\"parent/470\",[375,4.047]],[\"name/471\",[165,49.376]],[\"parent/471\",[375,4.047]],[\"name/472\",[250,52.74]],[\"parent/472\",[375,4.047]],[\"name/473\",[255,35.876]],[\"parent/473\",[375,4.047]],[\"name/474\",[377,38.389]],[\"parent/474\",[]],[\"name/475\",[378,57.849]],[\"parent/475\",[377,3.721]],[\"name/476\",[379,57.849]],[\"parent/476\",[377,3.721]],[\"name/477\",[380,57.849]],[\"parent/477\",[377,3.721]],[\"name/478\",[381,57.849]],[\"parent/478\",[377,3.721]],[\"name/479\",[382,57.849]],[\"parent/479\",[377,3.721]],[\"name/480\",[383,57.849]],[\"parent/480\",[377,3.721]],[\"name/481\",[384,57.849]],[\"parent/481\",[377,3.721]],[\"name/482\",[385,57.849]],[\"parent/482\",[377,3.721]],[\"name/483\",[255,35.876]],[\"parent/483\",[377,3.721]],[\"name/484\",[386,49.376]],[\"parent/484\",[]],[\"name/485\",[387,57.849]],[\"parent/485\",[386,4.786]],[\"name/486\",[255,35.876]],[\"parent/486\",[386,4.786]]],\"invertedIndex\":[[\"__type\",{\"_index\":309,\"name\":{\"376\":{},\"456\":{}},\"parent\":{}}],[\"accountstatus\",{\"_index\":85,\"name\":{\"88\":{},\"94\":{}},\"parent\":{}}],[\"addattachmentstodatabase\",{\"_index\":304,\"name\":{\"370\":{}},\"parent\":{}}],[\"addjobapplicationtodatabase\",{\"_index\":302,\"name\":{\"368\":{}},\"parent\":{}}],[\"addpersontodatabase\",{\"_index\":300,\"name\":{\"366\":{}},\"parent\":{}}],[\"addpronouns\",{\"_index\":316,\"name\":{\"386\":{}},\"parent\":{}}],[\"addrolestodatabase\",{\"_index\":305,\"name\":{\"371\":{}},\"parent\":{}}],[\"addsessionkey\",{\"_index\":235,\"name\":{\"295\":{}},\"parent\":{}}],[\"addskillstodatabase\",{\"_index\":303,\"name\":{\"369\":{}},\"parent\":{}}],[\"addstudenttodatabase\",{\"_index\":301,\"name\":{\"367\":{}},\"parent\":{}}],[\"addstudenttoproject\",{\"_index\":25,\"name\":{\"25\":{},\"194\":{}},\"parent\":{}}],[\"alumni\",{\"_index\":94,\"name\":{\"101\":{},\"108\":{},\"412\":{}},\"parent\":{}}],[\"appliedrole\",{\"_index\":332,\"name\":{\"409\":{}},\"parent\":{}}],[\"appliedroleinput\",{\"_index\":333,\"name\":{\"410\":{}},\"parent\":{}}],[\"bestskill\",{\"_index\":334,\"name\":{\"411\":{}},\"parent\":{}}],[\"birthname\",{\"_index\":314,\"name\":{\"381\":{}},\"parent\":{}}],[\"cc\",{\"_index\":164,\"name\":{\"211\":{},\"218\":{}},\"parent\":{}}],[\"changeemailstatusofjobapplication\",{\"_index\":32,\"name\":{\"32\":{}},\"parent\":{}}],[\"checkcode\",{\"_index\":361,\"name\":{\"446\":{}},\"parent\":{}}],[\"checkiffinalevaluationexists\",{\"_index\":18,\"name\":{\"18\":{}},\"parent\":{}}],[\"checkquestionsexist\",{\"_index\":269,\"name\":{\"335\":{}},\"parent\":{}}],[\"checksessionkey\",{\"_index\":236,\"name\":{\"296\":{}},\"parent\":{}}],[\"checkstate\",{\"_index\":338,\"name\":{\"417\":{}},\"parent\":{}}],[\"checkwordinanswer\",{\"_index\":268,\"name\":{\"334\":{}},\"parent\":{}}],[\"content\",{\"_index\":162,\"name\":{\"209\":{},\"216\":{}},\"parent\":{}}],[\"contractid\",{\"_index\":109,\"name\":{\"127\":{}},\"parent\":{}}],[\"contractsbyproject\",{\"_index\":15,\"name\":{\"15\":{}},\"parent\":{}}],[\"contractsforstudent\",{\"_index\":14,\"name\":{\"14\":{}},\"parent\":{}}],[\"contractstatus\",{\"_index\":108,\"name\":{\"125\":{},\"130\":{}},\"parent\":{}}],[\"createappliedrole\",{\"_index\":1,\"name\":{\"1\":{},\"203\":{}},\"parent\":{}}],[\"createattachment\",{\"_index\":5,\"name\":{\"5\":{}},\"parent\":{}}],[\"createcontract\",{\"_index\":10,\"name\":{\"10\":{},\"120\":{}},\"parent\":{}}],[\"createdat\",{\"_index\":123,\"name\":{\"145\":{}},\"parent\":{}}],[\"createemail\",{\"_index\":363,\"name\":{\"449\":{}},\"parent\":{}}],[\"createevaluationforstudent\",{\"_index\":19,\"name\":{\"19\":{},\"109\":{}},\"parent\":{}}],[\"createform\",{\"_index\":306,\"name\":{\"372\":{}},\"parent\":{}}],[\"createjobapplication\",{\"_index\":34,\"name\":{\"34\":{},\"132\":{}},\"parent\":{}}],[\"createjobapplicationskill\",{\"_index\":39,\"name\":{\"39\":{},\"179\":{}},\"parent\":{}}],[\"createlanguage\",{\"_index\":47,\"name\":{\"47\":{}},\"parent\":{}}],[\"createloginuser\",{\"_index\":55,\"name\":{\"55\":{},\"83\":{}},\"parent\":{}}],[\"createorupdatereset\",{\"_index\":187,\"name\":{\"239\":{}},\"parent\":{}}],[\"createosoc\",{\"_index\":175,\"name\":{\"226\":{}},\"parent\":{}}],[\"createperson\",{\"_index\":71,\"name\":{\"71\":{},\"244\":{}},\"parent\":{}}],[\"createproject\",{\"_index\":127,\"name\":{\"149\":{},\"253\":{},\"430\":{}},\"parent\":{}}],[\"createprojectrole\",{\"_index\":137,\"name\":{\"164\":{},\"274\":{}},\"parent\":{}}],[\"createprojectrolefor\",{\"_index\":354,\"name\":{\"437\":{}},\"parent\":{}}],[\"createprojectuser\",{\"_index\":156,\"name\":{\"200\":{},\"283\":{}},\"parent\":{}}],[\"createrole\",{\"_index\":227,\"name\":{\"286\":{}},\"parent\":{}}],[\"createstudent\",{\"_index\":88,\"name\":{\"95\":{},\"301\":{}},\"parent\":{}}],[\"createstudentconfirmation\",{\"_index\":374,\"name\":{\"464\":{}},\"parent\":{}}],[\"createstudentrole\",{\"_index\":366,\"name\":{\"452\":{}},\"parent\":{}}],[\"createstudentsuggestion\",{\"_index\":372,\"name\":{\"462\":{}},\"parent\":{}}],[\"createtemplate\",{\"_index\":159,\"name\":{\"206\":{},\"312\":{},\"470\":{}},\"parent\":{}}],[\"createuseracceptance\",{\"_index\":381,\"name\":{\"478\":{}},\"parent\":{}}],[\"createuserrequest\",{\"_index\":379,\"name\":{\"476\":{}},\"parent\":{}}],[\"cvlink\",{\"_index\":324,\"name\":{\"395\":{}},\"parent\":{}}],[\"cvupload\",{\"_index\":323,\"name\":{\"394\":{}},\"parent\":{}}],[\"decision\",{\"_index\":100,\"name\":{\"112\":{},\"118\":{}},\"parent\":{}}],[\"deleteadmin\",{\"_index\":254,\"name\":{\"318\":{}},\"parent\":{}}],[\"deleteallattachmentsforapplication\",{\"_index\":7,\"name\":{\"7\":{}},\"parent\":{}}],[\"deleteappliedrolesbyjobapplication\",{\"_index\":3,\"name\":{\"3\":{}},\"parent\":{}}],[\"deleteattachment\",{\"_index\":6,\"name\":{\"6\":{}},\"parent\":{}}],[\"deletecoach\",{\"_index\":259,\"name\":{\"323\":{}},\"parent\":{}}],[\"deleteevaluationsbyjobapplication\",{\"_index\":23,\"name\":{\"23\":{}},\"parent\":{}}],[\"deletejobapplication\",{\"_index\":33,\"name\":{\"33\":{}},\"parent\":{}}],[\"deletejobapplicationsfromstudent\",{\"_index\":31,\"name\":{\"31\":{}},\"parent\":{}}],[\"deletejobapplicationskill\",{\"_index\":44,\"name\":{\"44\":{}},\"parent\":{}}],[\"deletelanguage\",{\"_index\":52,\"name\":{\"52\":{}},\"parent\":{}}],[\"deletelanguagebyname\",{\"_index\":53,\"name\":{\"53\":{}},\"parent\":{}}],[\"deleteloginuserbyid\",{\"_index\":64,\"name\":{\"64\":{}},\"parent\":{}}],[\"deleteloginuserbypersonid\",{\"_index\":65,\"name\":{\"65\":{}},\"parent\":{}}],[\"deleteosoc\",{\"_index\":181,\"name\":{\"233\":{}},\"parent\":{}}],[\"deleteosocbyyear\",{\"_index\":182,\"name\":{\"234\":{}},\"parent\":{}}],[\"deleteosocfromdb\",{\"_index\":183,\"name\":{\"235\":{}},\"parent\":{}}],[\"deletepersonbyid\",{\"_index\":197,\"name\":{\"251\":{}},\"parent\":{}}],[\"deleteproject\",{\"_index\":213,\"name\":{\"269\":{},\"434\":{}},\"parent\":{}}],[\"deleteprojectbyosocedition\",{\"_index\":214,\"name\":{\"270\":{}},\"parent\":{}}],[\"deleteprojectbypartner\",{\"_index\":215,\"name\":{\"271\":{}},\"parent\":{}}],[\"deleteprojectrole\",{\"_index\":221,\"name\":{\"279\":{}},\"parent\":{}}],[\"deleteresetwithloginuser\",{\"_index\":189,\"name\":{\"241\":{}},\"parent\":{}}],[\"deleteresetwithresetid\",{\"_index\":190,\"name\":{\"242\":{}},\"parent\":{}}],[\"deleterole\",{\"_index\":232,\"name\":{\"292\":{}},\"parent\":{}}],[\"deleterolebyname\",{\"_index\":233,\"name\":{\"293\":{}},\"parent\":{}}],[\"deleteskillsbyjobapplicationid\",{\"_index\":45,\"name\":{\"45\":{}},\"parent\":{}}],[\"deletestudent\",{\"_index\":243,\"name\":{\"305\":{},\"461\":{}},\"parent\":{}}],[\"deletetemplate\",{\"_index\":250,\"name\":{\"314\":{},\"472\":{}},\"parent\":{}}],[\"deleteuserrequest\",{\"_index\":382,\"name\":{\"479\":{}},\"parent\":{}}],[\"eduduration\",{\"_index\":119,\"name\":{\"141\":{},\"406\":{}},\"parent\":{}}],[\"eduinstitute\",{\"_index\":121,\"name\":{\"143\":{},\"408\":{}},\"parent\":{}}],[\"edulevel\",{\"_index\":118,\"name\":{\"140\":{},\"404\":{}},\"parent\":{}}],[\"edulevelinput\",{\"_index\":331,\"name\":{\"405\":{}},\"parent\":{}}],[\"edus\",{\"_index\":117,\"name\":{\"139\":{},\"402\":{}},\"parent\":{}}],[\"edusinput\",{\"_index\":330,\"name\":{\"403\":{}},\"parent\":{}}],[\"eduyear\",{\"_index\":120,\"name\":{\"142\":{},\"407\":{}},\"parent\":{}}],[\"email\",{\"_index\":76,\"name\":{\"75\":{},\"82\":{}},\"parent\":{}}],[\"emailaddress\",{\"_index\":322,\"name\":{\"393\":{}},\"parent\":{}}],[\"emailstatus\",{\"_index\":122,\"name\":{\"144\":{}},\"parent\":{}}],[\"enddate\",{\"_index\":132,\"name\":{\"154\":{},\"162\":{}},\"parent\":{}}],[\"englishlevel\",{\"_index\":321,\"name\":{\"391\":{}},\"parent\":{}}],[\"evaluation_id\",{\"_index\":103,\"name\":{\"116\":{}},\"parent\":{}}],[\"export\",{\"_index\":308,\"name\":{\"375\":{},\"455\":{}},\"parent\":{}}],[\"filterboolean\",{\"_index\":173,\"name\":{\"224\":{}},\"parent\":{}}],[\"filterchosenoption\",{\"_index\":267,\"name\":{\"333\":{}},\"parent\":{}}],[\"filterloginusers\",{\"_index\":67,\"name\":{\"67\":{}},\"parent\":{}}],[\"filternumber\",{\"_index\":170,\"name\":{\"221\":{}},\"parent\":{}}],[\"filternumberarray\",{\"_index\":171,\"name\":{\"222\":{}},\"parent\":{}}],[\"filterosocs\",{\"_index\":185,\"name\":{\"237\":{}},\"parent\":{}}],[\"filterprojects\",{\"_index\":216,\"name\":{\"272\":{},\"441\":{}},\"parent\":{}}],[\"filterquestion\",{\"_index\":266,\"name\":{\"332\":{}},\"parent\":{}}],[\"filtersort\",{\"_index\":168,\"name\":{\"219\":{}},\"parent\":{}}],[\"filterstring\",{\"_index\":169,\"name\":{\"220\":{}},\"parent\":{}}],[\"filterstringarray\",{\"_index\":172,\"name\":{\"223\":{}},\"parent\":{}}],[\"filterstudents\",{\"_index\":245,\"name\":{\"307\":{},\"465\":{}},\"parent\":{}}],[\"filterusers\",{\"_index\":383,\"name\":{\"480\":{}},\"parent\":{}}],[\"findresetbycode\",{\"_index\":188,\"name\":{\"240\":{}},\"parent\":{}}],[\"firstname\",{\"_index\":72,\"name\":{\"72\":{},\"79\":{}},\"parent\":{}}],[\"funfact\",{\"_index\":113,\"name\":{\"135\":{},\"401\":{}},\"parent\":{}}],[\"gender\",{\"_index\":90,\"name\":{\"97\":{},\"104\":{},\"385\":{}},\"parent\":{}}],[\"genstate\",{\"_index\":337,\"name\":{\"416\":{}},\"parent\":{}}],[\"getalljobapplicationskill\",{\"_index\":40,\"name\":{\"40\":{}},\"parent\":{}}],[\"getalljobapplicationskillbyjobapplication\",{\"_index\":41,\"name\":{\"41\":{}},\"parent\":{}}],[\"getalllanguages\",{\"_index\":48,\"name\":{\"48\":{}},\"parent\":{}}],[\"getallloginusers\",{\"_index\":56,\"name\":{\"56\":{}},\"parent\":{}}],[\"getallosoc\",{\"_index\":176,\"name\":{\"227\":{}},\"parent\":{}}],[\"getallpersons\",{\"_index\":192,\"name\":{\"245\":{}},\"parent\":{}}],[\"getallprojects\",{\"_index\":199,\"name\":{\"254\":{}},\"parent\":{}}],[\"getallroles\",{\"_index\":228,\"name\":{\"287\":{}},\"parent\":{}}],[\"getallstudents\",{\"_index\":241,\"name\":{\"302\":{}},\"parent\":{}}],[\"getalltemplates\",{\"_index\":247,\"name\":{\"309\":{},\"468\":{}},\"parent\":{}}],[\"getalumni\",{\"_index\":278,\"name\":{\"344\":{}},\"parent\":{}}],[\"getappliedroles\",{\"_index\":298,\"name\":{\"364\":{}},\"parent\":{}}],[\"getappliedrolesbyjobapplication\",{\"_index\":2,\"name\":{\"2\":{}},\"parent\":{}}],[\"getattachmentbyid\",{\"_index\":8,\"name\":{\"8\":{}},\"parent\":{}}],[\"getbestskill\",{\"_index\":292,\"name\":{\"358\":{}},\"parent\":{}}],[\"getbirthname\",{\"_index\":270,\"name\":{\"336\":{}},\"parent\":{}}],[\"getcoachrequests\",{\"_index\":260,\"name\":{\"324\":{}},\"parent\":{}}],[\"getcurrentuser\",{\"_index\":385,\"name\":{\"482\":{}},\"parent\":{}}],[\"getcv\",{\"_index\":294,\"name\":{\"360\":{}},\"parent\":{}}],[\"getdraftedstudents\",{\"_index\":352,\"name\":{\"435\":{}},\"parent\":{}}],[\"geteducationduration\",{\"_index\":286,\"name\":{\"352\":{}},\"parent\":{}}],[\"geteducationlevel\",{\"_index\":285,\"name\":{\"351\":{}},\"parent\":{}}],[\"geteducations\",{\"_index\":284,\"name\":{\"350\":{}},\"parent\":{}}],[\"geteducationuniversity\",{\"_index\":288,\"name\":{\"354\":{}},\"parent\":{}}],[\"geteducationyear\",{\"_index\":287,\"name\":{\"353\":{}},\"parent\":{}}],[\"getemail\",{\"_index\":272,\"name\":{\"338\":{}},\"parent\":{}}],[\"getenglishlevel\",{\"_index\":291,\"name\":{\"357\":{}},\"parent\":{}}],[\"getevaluationbypartiesfor\",{\"_index\":22,\"name\":{\"22\":{}},\"parent\":{}}],[\"getfollowup\",{\"_index\":263,\"name\":{\"328\":{}},\"parent\":{}}],[\"getfreespotsfor\",{\"_index\":353,\"name\":{\"436\":{}},\"parent\":{}}],[\"getfunfact\",{\"_index\":281,\"name\":{\"347\":{}},\"parent\":{}}],[\"getgender\",{\"_index\":275,\"name\":{\"341\":{}},\"parent\":{}}],[\"gethome\",{\"_index\":336,\"name\":{\"415\":{}},\"parent\":{}}],[\"getjobapplication\",{\"_index\":36,\"name\":{\"36\":{}},\"parent\":{}}],[\"getjobapplicationbyyear\",{\"_index\":37,\"name\":{\"37\":{}},\"parent\":{}}],[\"getjobapplicationskill\",{\"_index\":42,\"name\":{\"42\":{}},\"parent\":{}}],[\"getlanguage\",{\"_index\":49,\"name\":{\"49\":{}},\"parent\":{}}],[\"getlanguagebyname\",{\"_index\":50,\"name\":{\"50\":{}},\"parent\":{}}],[\"getlastname\",{\"_index\":271,\"name\":{\"337\":{}},\"parent\":{}}],[\"getlatestapplicationrolesforstudent\",{\"_index\":30,\"name\":{\"30\":{}},\"parent\":{}}],[\"getlatestjobapplicationofstudent\",{\"_index\":35,\"name\":{\"35\":{}},\"parent\":{}}],[\"getlatestosoc\",{\"_index\":177,\"name\":{\"228\":{}},\"parent\":{}}],[\"getloginuserbyevaluationid\",{\"_index\":21,\"name\":{\"21\":{}},\"parent\":{}}],[\"getloginuserbyid\",{\"_index\":66,\"name\":{\"66\":{}},\"parent\":{}}],[\"getmostfluentlanguage\",{\"_index\":290,\"name\":{\"356\":{}},\"parent\":{}}],[\"getmotivation\",{\"_index\":296,\"name\":{\"362\":{}},\"parent\":{}}],[\"getnewestosoc\",{\"_index\":184,\"name\":{\"236\":{}},\"parent\":{}}],[\"getnickname\",{\"_index\":277,\"name\":{\"343\":{}},\"parent\":{}}],[\"getnumberoffreepositions\",{\"_index\":222,\"name\":{\"280\":{}},\"parent\":{}}],[\"getnumberofrolesbyprojectandrole\",{\"_index\":219,\"name\":{\"276\":{}},\"parent\":{}}],[\"getosocafteryear\",{\"_index\":180,\"name\":{\"231\":{}},\"parent\":{}}],[\"getosocbeforeyear\",{\"_index\":179,\"name\":{\"230\":{}},\"parent\":{}}],[\"getosocbyyear\",{\"_index\":178,\"name\":{\"229\":{}},\"parent\":{}}],[\"getpasswordloginuser\",{\"_index\":58,\"name\":{\"58\":{}},\"parent\":{}}],[\"getpasswordloginuserbyperson\",{\"_index\":57,\"name\":{\"57\":{}},\"parent\":{}}],[\"getpasswordpersonbyemail\",{\"_index\":193,\"name\":{\"246\":{}},\"parent\":{}}],[\"getpasswordpersonbygithub\",{\"_index\":194,\"name\":{\"247\":{}},\"parent\":{}}],[\"getphonenumber\",{\"_index\":276,\"name\":{\"342\":{}},\"parent\":{}}],[\"getportfolio\",{\"_index\":295,\"name\":{\"361\":{}},\"parent\":{}}],[\"getproject\",{\"_index\":350,\"name\":{\"432\":{}},\"parent\":{}}],[\"getprojectbyid\",{\"_index\":200,\"name\":{\"255\":{}},\"parent\":{}}],[\"getprojectbyname\",{\"_index\":201,\"name\":{\"256\":{}},\"parent\":{}}],[\"getprojectconflicts\",{\"_index\":357,\"name\":{\"440\":{}},\"parent\":{}}],[\"getprojectrolebyid\",{\"_index\":223,\"name\":{\"281\":{}},\"parent\":{}}],[\"getprojectrolenamesbyproject\",{\"_index\":220,\"name\":{\"277\":{}},\"parent\":{}}],[\"getprojectrolesbyproject\",{\"_index\":218,\"name\":{\"275\":{}},\"parent\":{}}],[\"getprojectrolewithrolename\",{\"_index\":231,\"name\":{\"290\":{}},\"parent\":{}}],[\"getprojectsbyenddate\",{\"_index\":207,\"name\":{\"262\":{}},\"parent\":{}}],[\"getprojectsbynumberpositions\",{\"_index\":210,\"name\":{\"265\":{}},\"parent\":{}}],[\"getprojectsbyosocedition\",{\"_index\":202,\"name\":{\"257\":{}},\"parent\":{}}],[\"getprojectsbypartner\",{\"_index\":203,\"name\":{\"258\":{}},\"parent\":{}}],[\"getprojectsbystartdate\",{\"_index\":204,\"name\":{\"259\":{}},\"parent\":{}}],[\"getprojectsendedafterdate\",{\"_index\":208,\"name\":{\"263\":{}},\"parent\":{}}],[\"getprojectsendedbeforedate\",{\"_index\":209,\"name\":{\"264\":{}},\"parent\":{}}],[\"getprojectslesspositions\",{\"_index\":211,\"name\":{\"266\":{}},\"parent\":{}}],[\"getprojectsmorepositions\",{\"_index\":212,\"name\":{\"267\":{}},\"parent\":{}}],[\"getprojectsstartedafterdate\",{\"_index\":205,\"name\":{\"260\":{}},\"parent\":{}}],[\"getprojectsstartedbeforedate\",{\"_index\":206,\"name\":{\"261\":{}},\"parent\":{}}],[\"getpronouns\",{\"_index\":274,\"name\":{\"340\":{}},\"parent\":{}}],[\"getresponsibilities\",{\"_index\":280,\"name\":{\"346\":{}},\"parent\":{}}],[\"getrole\",{\"_index\":229,\"name\":{\"288\":{}},\"parent\":{}}],[\"getrolesbyname\",{\"_index\":230,\"name\":{\"289\":{}},\"parent\":{}}],[\"getrouter\",{\"_index\":255,\"name\":{\"319\":{},\"325\":{},\"330\":{},\"373\":{},\"423\":{},\"428\":{},\"442\":{},\"448\":{},\"453\":{},\"466\":{},\"473\":{},\"483\":{},\"486\":{}},\"parent\":{}}],[\"getsingletemplate\",{\"_index\":376,\"name\":{\"469\":{}},\"parent\":{}}],[\"getstudent\",{\"_index\":242,\"name\":{\"303\":{},\"460\":{}},\"parent\":{}}],[\"getstudentevaluationsfinal\",{\"_index\":28,\"name\":{\"28\":{}},\"parent\":{}}],[\"getstudentevaluationstemp\",{\"_index\":29,\"name\":{\"29\":{}},\"parent\":{}}],[\"getstudentevaluationstotal\",{\"_index\":27,\"name\":{\"27\":{}},\"parent\":{}}],[\"getstudentsuggestions\",{\"_index\":373,\"name\":{\"463\":{}},\"parent\":{}}],[\"gettemplatebyid\",{\"_index\":248,\"name\":{\"310\":{}},\"parent\":{}}],[\"gettemplatesbyname\",{\"_index\":249,\"name\":{\"311\":{}},\"parent\":{}}],[\"getusersfor\",{\"_index\":225,\"name\":{\"284\":{}},\"parent\":{}}],[\"getvolunteerinfo\",{\"_index\":282,\"name\":{\"348\":{}},\"parent\":{}}],[\"ghexchangeaccesstoken\",{\"_index\":340,\"name\":{\"419\":{}},\"parent\":{}}],[\"ghidentity\",{\"_index\":339,\"name\":{\"418\":{}},\"parent\":{}}],[\"ghsignuporlogin\",{\"_index\":343,\"name\":{\"422\":{}},\"parent\":{}}],[\"github\",{\"_index\":75,\"name\":{\"74\":{},\"81\":{}},\"parent\":{}}],[\"github_id\",{\"_index\":77,\"name\":{\"76\":{}},\"parent\":{}}],[\"githubnamechange\",{\"_index\":342,\"name\":{\"421\":{}},\"parent\":{}}],[\"information\",{\"_index\":107,\"name\":{\"123\":{},\"129\":{},\"199\":{}},\"parent\":{}}],[\"is_best\",{\"_index\":153,\"name\":{\"193\":{}},\"parent\":{}}],[\"isadmin\",{\"_index\":83,\"name\":{\"86\":{},\"92\":{}},\"parent\":{}}],[\"isbest\",{\"_index\":150,\"name\":{\"185\":{}},\"parent\":{}}],[\"iscoach\",{\"_index\":84,\"name\":{\"87\":{},\"93\":{}},\"parent\":{}}],[\"isfinal\",{\"_index\":102,\"name\":{\"114\":{}},\"parent\":{}}],[\"ispreferred\",{\"_index\":149,\"name\":{\"184\":{},\"192\":{}},\"parent\":{}}],[\"isstudentcoach\",{\"_index\":283,\"name\":{\"349\":{}},\"parent\":{}}],[\"jobapplicationid\",{\"_index\":99,\"name\":{\"111\":{},\"180\":{},\"188\":{},\"204\":{}},\"parent\":{}}],[\"jobapplicationskillid\",{\"_index\":151,\"name\":{\"187\":{}},\"parent\":{}}],[\"jsontoattachments\",{\"_index\":297,\"name\":{\"363\":{}},\"parent\":{}}],[\"jsontojobapplication\",{\"_index\":289,\"name\":{\"355\":{}},\"parent\":{}}],[\"jsontoperson\",{\"_index\":273,\"name\":{\"339\":{}},\"parent\":{}}],[\"jsontoroles\",{\"_index\":299,\"name\":{\"365\":{}},\"parent\":{}}],[\"jsontoskills\",{\"_index\":293,\"name\":{\"359\":{}},\"parent\":{}}],[\"jsontostudent\",{\"_index\":279,\"name\":{\"345\":{}},\"parent\":{}}],[\"languageid\",{\"_index\":144,\"name\":{\"177\":{},\"182\":{},\"190\":{}},\"parent\":{}}],[\"lastname\",{\"_index\":74,\"name\":{\"73\":{},\"80\":{},\"382\":{}},\"parent\":{}}],[\"level\",{\"_index\":148,\"name\":{\"183\":{},\"191\":{}},\"parent\":{}}],[\"listadmins\",{\"_index\":252,\"name\":{\"316\":{}},\"parent\":{}}],[\"listcoaches\",{\"_index\":257,\"name\":{\"321\":{}},\"parent\":{}}],[\"listfollowups\",{\"_index\":262,\"name\":{\"327\":{}},\"parent\":{}}],[\"listprojects\",{\"_index\":349,\"name\":{\"431\":{}},\"parent\":{}}],[\"liststudentroles\",{\"_index\":365,\"name\":{\"451\":{}},\"parent\":{}}],[\"liststudents\",{\"_index\":371,\"name\":{\"459\":{}},\"parent\":{}}],[\"listusers\",{\"_index\":378,\"name\":{\"475\":{}},\"parent\":{}}],[\"liveinbelgium\",{\"_index\":310,\"name\":{\"377\":{}},\"parent\":{}}],[\"login\",{\"_index\":346,\"name\":{\"426\":{}},\"parent\":{}}],[\"loginuserid\",{\"_index\":86,\"name\":{\"90\":{},\"110\":{},\"117\":{},\"124\":{},\"128\":{},\"195\":{},\"202\":{}},\"parent\":{}}],[\"logout\",{\"_index\":347,\"name\":{\"427\":{}},\"parent\":{}}],[\"modadmin\",{\"_index\":253,\"name\":{\"317\":{}},\"parent\":{}}],[\"modcoach\",{\"_index\":258,\"name\":{\"322\":{}},\"parent\":{}}],[\"modproject\",{\"_index\":351,\"name\":{\"433\":{}},\"parent\":{}}],[\"modprojectstudent\",{\"_index\":355,\"name\":{\"438\":{}},\"parent\":{}}],[\"mostfluentlanguage\",{\"_index\":319,\"name\":{\"389\":{}},\"parent\":{}}],[\"mostfluentlanguageinput\",{\"_index\":320,\"name\":{\"390\":{}},\"parent\":{}}],[\"motivation\",{\"_index\":101,\"name\":{\"113\":{},\"119\":{}},\"parent\":{}}],[\"motivationinput\",{\"_index\":329,\"name\":{\"400\":{}},\"parent\":{}}],[\"motivationlink\",{\"_index\":328,\"name\":{\"399\":{}},\"parent\":{}}],[\"motivationupload\",{\"_index\":327,\"name\":{\"398\":{}},\"parent\":{}}],[\"name\",{\"_index\":128,\"name\":{\"150\":{},\"158\":{},\"175\":{},\"178\":{},\"208\":{},\"215\":{}},\"parent\":{}}],[\"nickname\",{\"_index\":93,\"name\":{\"100\":{},\"107\":{},\"383\":{}},\"parent\":{}}],[\"nicknameinput\",{\"_index\":315,\"name\":{\"384\":{}},\"parent\":{}}],[\"orm_functions/applied_role\",{\"_index\":0,\"name\":{\"0\":{}},\"parent\":{\"1\":{},\"2\":{},\"3\":{}}}],[\"orm_functions/attachment\",{\"_index\":4,\"name\":{\"4\":{}},\"parent\":{\"5\":{},\"6\":{},\"7\":{},\"8\":{}}}],[\"orm_functions/contract\",{\"_index\":9,\"name\":{\"9\":{}},\"parent\":{\"10\":{},\"11\":{},\"12\":{},\"13\":{},\"14\":{},\"15\":{},\"16\":{}}}],[\"orm_functions/evaluation\",{\"_index\":17,\"name\":{\"17\":{}},\"parent\":{\"18\":{},\"19\":{},\"20\":{},\"21\":{},\"22\":{},\"23\":{}}}],[\"orm_functions/general_purpose\",{\"_index\":24,\"name\":{\"24\":{}},\"parent\":{\"25\":{}}}],[\"orm_functions/job_application\",{\"_index\":26,\"name\":{\"26\":{}},\"parent\":{\"27\":{},\"28\":{},\"29\":{},\"30\":{},\"31\":{},\"32\":{},\"33\":{},\"34\":{},\"35\":{},\"36\":{},\"37\":{}}}],[\"orm_functions/job_application_skill\",{\"_index\":38,\"name\":{\"38\":{}},\"parent\":{\"39\":{},\"40\":{},\"41\":{},\"42\":{},\"43\":{},\"44\":{},\"45\":{}}}],[\"orm_functions/language\",{\"_index\":46,\"name\":{\"46\":{}},\"parent\":{\"47\":{},\"48\":{},\"49\":{},\"50\":{},\"51\":{},\"52\":{},\"53\":{}}}],[\"orm_functions/login_user\",{\"_index\":54,\"name\":{\"54\":{}},\"parent\":{\"55\":{},\"56\":{},\"57\":{},\"58\":{},\"59\":{},\"60\":{},\"61\":{},\"62\":{},\"63\":{},\"64\":{},\"65\":{},\"66\":{},\"67\":{},\"68\":{},\"69\":{}}}],[\"orm_functions/orm_types\",{\"_index\":70,\"name\":{\"70\":{}},\"parent\":{\"71\":{},\"77\":{},\"83\":{},\"89\":{},\"95\":{},\"102\":{},\"109\":{},\"115\":{},\"120\":{},\"126\":{},\"132\":{},\"146\":{},\"149\":{},\"156\":{},\"164\":{},\"168\":{},\"173\":{},\"176\":{},\"179\":{},\"186\":{},\"194\":{},\"200\":{},\"203\":{},\"206\":{},\"212\":{},\"219\":{},\"220\":{},\"221\":{},\"222\":{},\"223\":{},\"224\":{}}}],[\"orm_functions/orm_types.addstudenttoproject\",{\"_index\":154,\"name\":{},\"parent\":{\"195\":{},\"196\":{},\"197\":{},\"198\":{},\"199\":{}}}],[\"orm_functions/orm_types.createappliedrole\",{\"_index\":158,\"name\":{},\"parent\":{\"204\":{},\"205\":{}}}],[\"orm_functions/orm_types.createcontract\",{\"_index\":105,\"name\":{},\"parent\":{\"121\":{},\"122\":{},\"123\":{},\"124\":{},\"125\":{}}}],[\"orm_functions/orm_types.createevaluationforstudent\",{\"_index\":98,\"name\":{},\"parent\":{\"110\":{},\"111\":{},\"112\":{},\"113\":{},\"114\":{}}}],[\"orm_functions/orm_types.createjobapplication\",{\"_index\":111,\"name\":{},\"parent\":{\"133\":{},\"134\":{},\"135\":{},\"136\":{},\"137\":{},\"138\":{},\"139\":{},\"140\":{},\"141\":{},\"142\":{},\"143\":{},\"144\":{},\"145\":{}}}],[\"orm_functions/orm_types.createjobapplicationskill\",{\"_index\":146,\"name\":{},\"parent\":{\"180\":{},\"181\":{},\"182\":{},\"183\":{},\"184\":{},\"185\":{}}}],[\"orm_functions/orm_types.createloginuser\",{\"_index\":81,\"name\":{},\"parent\":{\"84\":{},\"85\":{},\"86\":{},\"87\":{},\"88\":{}}}],[\"orm_functions/orm_types.createperson\",{\"_index\":73,\"name\":{},\"parent\":{\"72\":{},\"73\":{},\"74\":{},\"75\":{},\"76\":{}}}],[\"orm_functions/orm_types.createproject\",{\"_index\":129,\"name\":{},\"parent\":{\"150\":{},\"151\":{},\"152\":{},\"153\":{},\"154\":{},\"155\":{}}}],[\"orm_functions/orm_types.createprojectrole\",{\"_index\":138,\"name\":{},\"parent\":{\"165\":{},\"166\":{},\"167\":{}}}],[\"orm_functions/orm_types.createprojectuser\",{\"_index\":157,\"name\":{},\"parent\":{\"201\":{},\"202\":{}}}],[\"orm_functions/orm_types.createstudent\",{\"_index\":89,\"name\":{},\"parent\":{\"96\":{},\"97\":{},\"98\":{},\"99\":{},\"100\":{},\"101\":{}}}],[\"orm_functions/orm_types.createtemplate\",{\"_index\":161,\"name\":{},\"parent\":{\"207\":{},\"208\":{},\"209\":{},\"210\":{},\"211\":{}}}],[\"orm_functions/orm_types.updatecontract\",{\"_index\":110,\"name\":{},\"parent\":{\"127\":{},\"128\":{},\"129\":{},\"130\":{},\"131\":{}}}],[\"orm_functions/orm_types.updateevaluationforstudent\",{\"_index\":104,\"name\":{},\"parent\":{\"116\":{},\"117\":{},\"118\":{},\"119\":{}}}],[\"orm_functions/orm_types.updatejobapplicationskill\",{\"_index\":152,\"name\":{},\"parent\":{\"187\":{},\"188\":{},\"189\":{},\"190\":{},\"191\":{},\"192\":{},\"193\":{}}}],[\"orm_functions/orm_types.updatelanguage\",{\"_index\":145,\"name\":{},\"parent\":{\"177\":{},\"178\":{}}}],[\"orm_functions/orm_types.updateloginuser\",{\"_index\":87,\"name\":{},\"parent\":{\"90\":{},\"91\":{},\"92\":{},\"93\":{},\"94\":{}}}],[\"orm_functions/orm_types.updateosoc\",{\"_index\":125,\"name\":{},\"parent\":{\"147\":{},\"148\":{}}}],[\"orm_functions/orm_types.updateperson\",{\"_index\":80,\"name\":{},\"parent\":{\"78\":{},\"79\":{},\"80\":{},\"81\":{},\"82\":{}}}],[\"orm_functions/orm_types.updateproject\",{\"_index\":136,\"name\":{},\"parent\":{\"157\":{},\"158\":{},\"159\":{},\"160\":{},\"161\":{},\"162\":{},\"163\":{}}}],[\"orm_functions/orm_types.updateprojectrole\",{\"_index\":141,\"name\":{},\"parent\":{\"169\":{},\"170\":{},\"171\":{},\"172\":{}}}],[\"orm_functions/orm_types.updaterole\",{\"_index\":143,\"name\":{},\"parent\":{\"174\":{},\"175\":{}}}],[\"orm_functions/orm_types.updatestudent\",{\"_index\":97,\"name\":{},\"parent\":{\"103\":{},\"104\":{},\"105\":{},\"106\":{},\"107\":{},\"108\":{}}}],[\"orm_functions/orm_types.updatetemplate\",{\"_index\":167,\"name\":{},\"parent\":{\"213\":{},\"214\":{},\"215\":{},\"216\":{},\"217\":{},\"218\":{}}}],[\"orm_functions/osoc\",{\"_index\":174,\"name\":{\"225\":{}},\"parent\":{\"226\":{},\"227\":{},\"228\":{},\"229\":{},\"230\":{},\"231\":{},\"232\":{},\"233\":{},\"234\":{},\"235\":{},\"236\":{},\"237\":{}}}],[\"orm_functions/password_reset\",{\"_index\":186,\"name\":{\"238\":{}},\"parent\":{\"239\":{},\"240\":{},\"241\":{},\"242\":{}}}],[\"orm_functions/person\",{\"_index\":191,\"name\":{\"243\":{}},\"parent\":{\"244\":{},\"245\":{},\"246\":{},\"247\":{},\"248\":{},\"249\":{},\"250\":{},\"251\":{}}}],[\"orm_functions/project\",{\"_index\":198,\"name\":{\"252\":{}},\"parent\":{\"253\":{},\"254\":{},\"255\":{},\"256\":{},\"257\":{},\"258\":{},\"259\":{},\"260\":{},\"261\":{},\"262\":{},\"263\":{},\"264\":{},\"265\":{},\"266\":{},\"267\":{},\"268\":{},\"269\":{},\"270\":{},\"271\":{},\"272\":{}}}],[\"orm_functions/project_role\",{\"_index\":217,\"name\":{\"273\":{}},\"parent\":{\"274\":{},\"275\":{},\"276\":{},\"277\":{},\"278\":{},\"279\":{},\"280\":{},\"281\":{}}}],[\"orm_functions/project_user\",{\"_index\":224,\"name\":{\"282\":{}},\"parent\":{\"283\":{},\"284\":{}}}],[\"orm_functions/role\",{\"_index\":226,\"name\":{\"285\":{}},\"parent\":{\"286\":{},\"287\":{},\"288\":{},\"289\":{},\"290\":{},\"291\":{},\"292\":{},\"293\":{}}}],[\"orm_functions/session_key\",{\"_index\":234,\"name\":{\"294\":{}},\"parent\":{\"295\":{},\"296\":{},\"297\":{},\"298\":{},\"299\":{}}}],[\"orm_functions/student\",{\"_index\":240,\"name\":{\"300\":{}},\"parent\":{\"301\":{},\"302\":{},\"303\":{},\"304\":{},\"305\":{},\"306\":{},\"307\":{}}}],[\"orm_functions/template\",{\"_index\":246,\"name\":{\"308\":{}},\"parent\":{\"309\":{},\"310\":{},\"311\":{},\"312\":{},\"313\":{},\"314\":{}}}],[\"osocid\",{\"_index\":116,\"name\":{\"138\":{},\"147\":{},\"151\":{},\"159\":{}},\"parent\":{}}],[\"ownerid\",{\"_index\":160,\"name\":{\"207\":{},\"214\":{}},\"parent\":{}}],[\"parseghlogin\",{\"_index\":341,\"name\":{\"420\":{}},\"parent\":{}}],[\"partner\",{\"_index\":130,\"name\":{\"152\":{},\"160\":{}},\"parent\":{}}],[\"password\",{\"_index\":82,\"name\":{\"85\":{},\"91\":{}},\"parent\":{}}],[\"personid\",{\"_index\":79,\"name\":{\"78\":{},\"84\":{},\"96\":{}},\"parent\":{}}],[\"phonenumber\",{\"_index\":92,\"name\":{\"99\":{},\"106\":{},\"392\":{}},\"parent\":{}}],[\"portfoliolink\",{\"_index\":326,\"name\":{\"397\":{}},\"parent\":{}}],[\"portfolioupload\",{\"_index\":325,\"name\":{\"396\":{}},\"parent\":{}}],[\"positions\",{\"_index\":133,\"name\":{\"155\":{},\"163\":{},\"167\":{},\"172\":{}},\"parent\":{}}],[\"preferredpronouns\",{\"_index\":317,\"name\":{\"387\":{}},\"parent\":{}}],[\"projectid\",{\"_index\":135,\"name\":{\"157\":{},\"165\":{},\"170\":{},\"197\":{},\"201\":{}},\"parent\":{}}],[\"projectroleid\",{\"_index\":106,\"name\":{\"122\":{},\"131\":{},\"169\":{}},\"parent\":{}}],[\"pronouns\",{\"_index\":91,\"name\":{\"98\":{},\"105\":{}},\"parent\":{}}],[\"pronounsinput\",{\"_index\":318,\"name\":{\"388\":{}},\"parent\":{}}],[\"refreshkey\",{\"_index\":237,\"name\":{\"297\":{}},\"parent\":{}}],[\"removeallkeysforloginuserid\",{\"_index\":239,\"name\":{\"299\":{}},\"parent\":{}}],[\"removeallkeysforuser\",{\"_index\":238,\"name\":{\"298\":{}},\"parent\":{}}],[\"removecontract\",{\"_index\":13,\"name\":{\"13\":{}},\"parent\":{}}],[\"removecontractsfromstudent\",{\"_index\":12,\"name\":{\"12\":{}},\"parent\":{}}],[\"requestreset\",{\"_index\":360,\"name\":{\"445\":{}},\"parent\":{}}],[\"resetpassword\",{\"_index\":362,\"name\":{\"447\":{}},\"parent\":{}}],[\"responsibilities\",{\"_index\":112,\"name\":{\"134\":{},\"380\":{}},\"parent\":{}}],[\"roleid\",{\"_index\":139,\"name\":{\"166\":{},\"171\":{},\"174\":{},\"205\":{}},\"parent\":{}}],[\"rolename\",{\"_index\":155,\"name\":{\"198\":{}},\"parent\":{}}],[\"routes/admin\",{\"_index\":251,\"name\":{\"315\":{}},\"parent\":{\"316\":{},\"317\":{},\"318\":{},\"319\":{}}}],[\"routes/coach\",{\"_index\":256,\"name\":{\"320\":{}},\"parent\":{\"321\":{},\"322\":{},\"323\":{},\"324\":{},\"325\":{}}}],[\"routes/followup\",{\"_index\":261,\"name\":{\"326\":{}},\"parent\":{\"327\":{},\"328\":{},\"329\":{},\"330\":{}}}],[\"routes/form\",{\"_index\":265,\"name\":{\"331\":{}},\"parent\":{\"332\":{},\"333\":{},\"334\":{},\"335\":{},\"336\":{},\"337\":{},\"338\":{},\"339\":{},\"340\":{},\"341\":{},\"342\":{},\"343\":{},\"344\":{},\"345\":{},\"346\":{},\"347\":{},\"348\":{},\"349\":{},\"350\":{},\"351\":{},\"352\":{},\"353\":{},\"354\":{},\"355\":{},\"356\":{},\"357\":{},\"358\":{},\"359\":{},\"360\":{},\"361\":{},\"362\":{},\"363\":{},\"364\":{},\"365\":{},\"366\":{},\"367\":{},\"368\":{},\"369\":{},\"370\":{},\"371\":{},\"372\":{},\"373\":{}}}],[\"routes/form_keys.json\",{\"_index\":307,\"name\":{\"374\":{}},\"parent\":{\"375\":{},\"376\":{}}}],[\"routes/form_keys.json.__type\",{\"_index\":311,\"name\":{},\"parent\":{\"377\":{},\"378\":{},\"379\":{},\"380\":{},\"381\":{},\"382\":{},\"383\":{},\"384\":{},\"385\":{},\"386\":{},\"387\":{},\"388\":{},\"389\":{},\"390\":{},\"391\":{},\"392\":{},\"393\":{},\"394\":{},\"395\":{},\"396\":{},\"397\":{},\"398\":{},\"399\":{},\"400\":{},\"401\":{},\"402\":{},\"403\":{},\"404\":{},\"405\":{},\"406\":{},\"407\":{},\"408\":{},\"409\":{},\"410\":{},\"411\":{},\"412\":{},\"413\":{}}}],[\"routes/github\",{\"_index\":335,\"name\":{\"414\":{}},\"parent\":{\"415\":{},\"416\":{},\"417\":{},\"418\":{},\"419\":{},\"420\":{},\"421\":{},\"422\":{},\"423\":{},\"424\":{}}}],[\"routes/login\",{\"_index\":345,\"name\":{\"425\":{}},\"parent\":{\"426\":{},\"427\":{},\"428\":{}}}],[\"routes/project\",{\"_index\":348,\"name\":{\"429\":{}},\"parent\":{\"430\":{},\"431\":{},\"432\":{},\"433\":{},\"434\":{},\"435\":{},\"436\":{},\"437\":{},\"438\":{},\"439\":{},\"440\":{},\"441\":{},\"442\":{}}}],[\"routes/reset\",{\"_index\":358,\"name\":{\"443\":{}},\"parent\":{\"444\":{},\"445\":{},\"446\":{},\"447\":{},\"448\":{},\"449\":{}}}],[\"routes/role\",{\"_index\":364,\"name\":{\"450\":{}},\"parent\":{\"451\":{},\"452\":{},\"453\":{}}}],[\"routes/session_key.json\",{\"_index\":367,\"name\":{\"454\":{}},\"parent\":{\"455\":{},\"456\":{}}}],[\"routes/session_key.json.__type\",{\"_index\":369,\"name\":{},\"parent\":{\"457\":{}}}],[\"routes/student\",{\"_index\":370,\"name\":{\"458\":{}},\"parent\":{\"459\":{},\"460\":{},\"461\":{},\"462\":{},\"463\":{},\"464\":{},\"465\":{},\"466\":{}}}],[\"routes/template\",{\"_index\":375,\"name\":{\"467\":{}},\"parent\":{\"468\":{},\"469\":{},\"470\":{},\"471\":{},\"472\":{},\"473\":{}}}],[\"routes/user\",{\"_index\":377,\"name\":{\"474\":{}},\"parent\":{\"475\":{},\"476\":{},\"477\":{},\"478\":{},\"479\":{},\"480\":{},\"481\":{},\"482\":{},\"483\":{}}}],[\"routes/verify\",{\"_index\":386,\"name\":{\"484\":{}},\"parent\":{\"485\":{},\"486\":{}}}],[\"searchalladminandcoachloginusers\",{\"_index\":62,\"name\":{\"62\":{}},\"parent\":{}}],[\"searchalladminloginusers\",{\"_index\":60,\"name\":{\"60\":{}},\"parent\":{}}],[\"searchallcoachloginusers\",{\"_index\":61,\"name\":{\"61\":{}},\"parent\":{}}],[\"searchloginuserbyperson\",{\"_index\":59,\"name\":{\"59\":{}},\"parent\":{}}],[\"searchpersonbylogin\",{\"_index\":196,\"name\":{\"249\":{}},\"parent\":{}}],[\"searchpersonbyname\",{\"_index\":195,\"name\":{\"248\":{}},\"parent\":{}}],[\"searchstudentbygender\",{\"_index\":244,\"name\":{\"306\":{}},\"parent\":{}}],[\"sendmail\",{\"_index\":359,\"name\":{\"444\":{}},\"parent\":{}}],[\"setaccountstatus\",{\"_index\":380,\"name\":{\"477\":{}},\"parent\":{}}],[\"setadmin\",{\"_index\":69,\"name\":{\"69\":{}},\"parent\":{}}],[\"setcoach\",{\"_index\":68,\"name\":{\"68\":{}},\"parent\":{}}],[\"skill\",{\"_index\":147,\"name\":{\"181\":{},\"189\":{}},\"parent\":{}}],[\"sortedcontractsbyosocedition\",{\"_index\":16,\"name\":{\"16\":{}},\"parent\":{}}],[\"startdate\",{\"_index\":131,\"name\":{\"153\":{},\"161\":{}},\"parent\":{}}],[\"states\",{\"_index\":344,\"name\":{\"424\":{}},\"parent\":{}}],[\"studentcoach\",{\"_index\":115,\"name\":{\"137\":{},\"413\":{}},\"parent\":{}}],[\"studentid\",{\"_index\":96,\"name\":{\"103\":{},\"121\":{},\"133\":{},\"196\":{}},\"parent\":{}}],[\"studentvolunteerinfo\",{\"_index\":114,\"name\":{\"136\":{}},\"parent\":{}}],[\"subject\",{\"_index\":163,\"name\":{\"210\":{},\"217\":{}},\"parent\":{}}],[\"templateid\",{\"_index\":166,\"name\":{\"213\":{}},\"parent\":{}}],[\"unassignstudent\",{\"_index\":356,\"name\":{\"439\":{}},\"parent\":{}}],[\"updatecontract\",{\"_index\":11,\"name\":{\"11\":{},\"126\":{}},\"parent\":{}}],[\"updateevaluationforstudent\",{\"_index\":20,\"name\":{\"20\":{},\"115\":{}},\"parent\":{}}],[\"updatefollowup\",{\"_index\":264,\"name\":{\"329\":{}},\"parent\":{}}],[\"updatejobapplicationskill\",{\"_index\":43,\"name\":{\"43\":{},\"186\":{}},\"parent\":{}}],[\"updatelanguage\",{\"_index\":51,\"name\":{\"51\":{},\"176\":{}},\"parent\":{}}],[\"updateloginuser\",{\"_index\":63,\"name\":{\"63\":{},\"89\":{}},\"parent\":{}}],[\"updateosoc\",{\"_index\":124,\"name\":{\"146\":{},\"232\":{}},\"parent\":{}}],[\"updateperson\",{\"_index\":78,\"name\":{\"77\":{},\"250\":{}},\"parent\":{}}],[\"updateproject\",{\"_index\":134,\"name\":{\"156\":{},\"268\":{}},\"parent\":{}}],[\"updateprojectrole\",{\"_index\":140,\"name\":{\"168\":{},\"278\":{}},\"parent\":{}}],[\"updaterole\",{\"_index\":142,\"name\":{\"173\":{},\"291\":{}},\"parent\":{}}],[\"updatestudent\",{\"_index\":95,\"name\":{\"102\":{},\"304\":{}},\"parent\":{}}],[\"updatetemplate\",{\"_index\":165,\"name\":{\"212\":{},\"313\":{},\"471\":{}},\"parent\":{}}],[\"usermodself\",{\"_index\":384,\"name\":{\"481\":{}},\"parent\":{}}],[\"valid_period\",{\"_index\":368,\"name\":{\"457\":{}},\"parent\":{}}],[\"verifykey\",{\"_index\":387,\"name\":{\"485\":{}},\"parent\":{}}],[\"volunteerinfo\",{\"_index\":312,\"name\":{\"378\":{}},\"parent\":{}}],[\"workinjuly\",{\"_index\":313,\"name\":{\"379\":{}},\"parent\":{}}],[\"year\",{\"_index\":126,\"name\":{\"148\":{}},\"parent\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file +window.searchData = JSON.parse("{\"kinds\":{\"2\":\"Module\",\"32\":\"Variable\",\"64\":\"Function\",\"256\":\"Interface\",\"1024\":\"Property\",\"65536\":\"Type literal\",\"4194304\":\"Type alias\"},\"rows\":[{\"id\":0,\"kind\":2,\"name\":\"routes/admin\",\"url\":\"modules/routes_admin.html\",\"classes\":\"tsd-kind-module\"},{\"id\":1,\"kind\":64,\"name\":\"listAdmins\",\"url\":\"modules/routes_admin.html#listAdmins\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":2,\"kind\":64,\"name\":\"modAdmin\",\"url\":\"modules/routes_admin.html#modAdmin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":3,\"kind\":64,\"name\":\"deleteAdmin\",\"url\":\"modules/routes_admin.html#deleteAdmin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":4,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_admin.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/admin\"},{\"id\":5,\"kind\":2,\"name\":\"routes/coach\",\"url\":\"modules/routes_coach.html\",\"classes\":\"tsd-kind-module\"},{\"id\":6,\"kind\":64,\"name\":\"listCoaches\",\"url\":\"modules/routes_coach.html#listCoaches\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":7,\"kind\":64,\"name\":\"modCoach\",\"url\":\"modules/routes_coach.html#modCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":8,\"kind\":64,\"name\":\"deleteCoach\",\"url\":\"modules/routes_coach.html#deleteCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":9,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_coach.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/coach\"},{\"id\":10,\"kind\":2,\"name\":\"routes/followup\",\"url\":\"modules/routes_followup.html\",\"classes\":\"tsd-kind-module\"},{\"id\":11,\"kind\":64,\"name\":\"getFollowup\",\"url\":\"modules/routes_followup.html#getFollowup\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/followup\"},{\"id\":12,\"kind\":64,\"name\":\"updateFollowup\",\"url\":\"modules/routes_followup.html#updateFollowup\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/followup\"},{\"id\":13,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_followup.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/followup\"},{\"id\":14,\"kind\":2,\"name\":\"routes/form\",\"url\":\"modules/routes_form.html\",\"classes\":\"tsd-kind-module\"},{\"id\":15,\"kind\":64,\"name\":\"filterQuestion\",\"url\":\"modules/routes_form.html#filterQuestion\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":16,\"kind\":64,\"name\":\"filterChosenOption\",\"url\":\"modules/routes_form.html#filterChosenOption\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":17,\"kind\":64,\"name\":\"checkWordInAnswer\",\"url\":\"modules/routes_form.html#checkWordInAnswer\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":18,\"kind\":64,\"name\":\"checkQuestionsExist\",\"url\":\"modules/routes_form.html#checkQuestionsExist\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":19,\"kind\":64,\"name\":\"getBirthName\",\"url\":\"modules/routes_form.html#getBirthName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":20,\"kind\":64,\"name\":\"getLastName\",\"url\":\"modules/routes_form.html#getLastName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":21,\"kind\":64,\"name\":\"getEmail\",\"url\":\"modules/routes_form.html#getEmail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":22,\"kind\":64,\"name\":\"jsonToPerson\",\"url\":\"modules/routes_form.html#jsonToPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":23,\"kind\":64,\"name\":\"getPronouns\",\"url\":\"modules/routes_form.html#getPronouns\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":24,\"kind\":64,\"name\":\"getGender\",\"url\":\"modules/routes_form.html#getGender\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":25,\"kind\":64,\"name\":\"getPhoneNumber\",\"url\":\"modules/routes_form.html#getPhoneNumber\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":26,\"kind\":64,\"name\":\"getNickname\",\"url\":\"modules/routes_form.html#getNickname\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":27,\"kind\":64,\"name\":\"getAlumni\",\"url\":\"modules/routes_form.html#getAlumni\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":28,\"kind\":64,\"name\":\"jsonToStudent\",\"url\":\"modules/routes_form.html#jsonToStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":29,\"kind\":64,\"name\":\"getResponsibilities\",\"url\":\"modules/routes_form.html#getResponsibilities\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":30,\"kind\":64,\"name\":\"getFunFact\",\"url\":\"modules/routes_form.html#getFunFact\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":31,\"kind\":64,\"name\":\"getVolunteerInfo\",\"url\":\"modules/routes_form.html#getVolunteerInfo\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":32,\"kind\":64,\"name\":\"isStudentCoach\",\"url\":\"modules/routes_form.html#isStudentCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":33,\"kind\":64,\"name\":\"getEducations\",\"url\":\"modules/routes_form.html#getEducations\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":34,\"kind\":64,\"name\":\"getEducationLevel\",\"url\":\"modules/routes_form.html#getEducationLevel\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":35,\"kind\":64,\"name\":\"getEducationDuration\",\"url\":\"modules/routes_form.html#getEducationDuration\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":36,\"kind\":64,\"name\":\"getEducationYear\",\"url\":\"modules/routes_form.html#getEducationYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":37,\"kind\":64,\"name\":\"getEducationUniversity\",\"url\":\"modules/routes_form.html#getEducationUniversity\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":38,\"kind\":64,\"name\":\"jsonToJobApplication\",\"url\":\"modules/routes_form.html#jsonToJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":39,\"kind\":64,\"name\":\"getMostFluentLanguage\",\"url\":\"modules/routes_form.html#getMostFluentLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":40,\"kind\":64,\"name\":\"getEnglishLevel\",\"url\":\"modules/routes_form.html#getEnglishLevel\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":41,\"kind\":64,\"name\":\"getBestSkill\",\"url\":\"modules/routes_form.html#getBestSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":42,\"kind\":64,\"name\":\"jsonToSkills\",\"url\":\"modules/routes_form.html#jsonToSkills\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":43,\"kind\":64,\"name\":\"getCV\",\"url\":\"modules/routes_form.html#getCV\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":44,\"kind\":64,\"name\":\"getPortfolio\",\"url\":\"modules/routes_form.html#getPortfolio\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":45,\"kind\":64,\"name\":\"getMotivation\",\"url\":\"modules/routes_form.html#getMotivation\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":46,\"kind\":64,\"name\":\"jsonToAttachments\",\"url\":\"modules/routes_form.html#jsonToAttachments\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":47,\"kind\":64,\"name\":\"getAppliedRoles\",\"url\":\"modules/routes_form.html#getAppliedRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":48,\"kind\":64,\"name\":\"jsonToRoles\",\"url\":\"modules/routes_form.html#jsonToRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":49,\"kind\":64,\"name\":\"addPersonToDatabase\",\"url\":\"modules/routes_form.html#addPersonToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":50,\"kind\":64,\"name\":\"addStudentToDatabase\",\"url\":\"modules/routes_form.html#addStudentToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":51,\"kind\":64,\"name\":\"addJobApplicationToDatabase\",\"url\":\"modules/routes_form.html#addJobApplicationToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":52,\"kind\":64,\"name\":\"addSkillsToDatabase\",\"url\":\"modules/routes_form.html#addSkillsToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":53,\"kind\":64,\"name\":\"addAttachmentsToDatabase\",\"url\":\"modules/routes_form.html#addAttachmentsToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":54,\"kind\":64,\"name\":\"addRolesToDatabase\",\"url\":\"modules/routes_form.html#addRolesToDatabase\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":55,\"kind\":64,\"name\":\"createForm\",\"url\":\"modules/routes_form.html#createForm\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":56,\"kind\":64,\"name\":\"readFile\",\"url\":\"modules/routes_form.html#readFile\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":57,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_form.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/form\"},{\"id\":58,\"kind\":2,\"name\":\"routes/github\",\"url\":\"modules/routes_github.html\",\"classes\":\"tsd-kind-module\"},{\"id\":59,\"kind\":64,\"name\":\"getHome\",\"url\":\"modules/routes_github.html#getHome\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":60,\"kind\":64,\"name\":\"genState\",\"url\":\"modules/routes_github.html#genState\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":61,\"kind\":64,\"name\":\"checkState\",\"url\":\"modules/routes_github.html#checkState\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":62,\"kind\":64,\"name\":\"ghIdentity\",\"url\":\"modules/routes_github.html#ghIdentity\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":63,\"kind\":64,\"name\":\"ghExchangeAccessToken\",\"url\":\"modules/routes_github.html#ghExchangeAccessToken\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":64,\"kind\":64,\"name\":\"parseGHLogin\",\"url\":\"modules/routes_github.html#parseGHLogin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":65,\"kind\":64,\"name\":\"githubNameChange\",\"url\":\"modules/routes_github.html#githubNameChange\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":66,\"kind\":64,\"name\":\"ghSignupOrLogin\",\"url\":\"modules/routes_github.html#ghSignupOrLogin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":67,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_github.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":68,\"kind\":32,\"name\":\"states\",\"url\":\"modules/routes_github.html#states\",\"classes\":\"tsd-kind-variable tsd-parent-kind-module\",\"parent\":\"routes/github\"},{\"id\":69,\"kind\":65536,\"name\":\"__type\",\"url\":\"modules/routes_github.html#states.__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-variable\",\"parent\":\"routes/github.states\"},{\"id\":70,\"kind\":2,\"name\":\"routes/login\",\"url\":\"modules/routes_login.html\",\"classes\":\"tsd-kind-module\"},{\"id\":71,\"kind\":64,\"name\":\"login\",\"url\":\"modules/routes_login.html#login\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/login\"},{\"id\":72,\"kind\":64,\"name\":\"logout\",\"url\":\"modules/routes_login.html#logout\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/login\"},{\"id\":73,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_login.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/login\"},{\"id\":74,\"kind\":2,\"name\":\"routes/osoc\",\"url\":\"modules/routes_osoc.html\",\"classes\":\"tsd-kind-module\"},{\"id\":75,\"kind\":64,\"name\":\"createOsocEdition\",\"url\":\"modules/routes_osoc.html#createOsocEdition\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/osoc\"},{\"id\":76,\"kind\":64,\"name\":\"listOsocEditions\",\"url\":\"modules/routes_osoc.html#listOsocEditions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/osoc\"},{\"id\":77,\"kind\":64,\"name\":\"filterYear\",\"url\":\"modules/routes_osoc.html#filterYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/osoc\"},{\"id\":78,\"kind\":64,\"name\":\"deleteOsocEditionRequest\",\"url\":\"modules/routes_osoc.html#deleteOsocEditionRequest\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/osoc\"},{\"id\":79,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_osoc.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/osoc\"},{\"id\":80,\"kind\":2,\"name\":\"routes/project\",\"url\":\"modules/routes_project.html\",\"classes\":\"tsd-kind-module\"},{\"id\":81,\"kind\":64,\"name\":\"createProject\",\"url\":\"modules/routes_project.html#createProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":82,\"kind\":64,\"name\":\"listProjects\",\"url\":\"modules/routes_project.html#listProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":83,\"kind\":64,\"name\":\"getProject\",\"url\":\"modules/routes_project.html#getProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":84,\"kind\":64,\"name\":\"modProject\",\"url\":\"modules/routes_project.html#modProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":85,\"kind\":64,\"name\":\"deleteProject\",\"url\":\"modules/routes_project.html#deleteProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":86,\"kind\":64,\"name\":\"getDraftedStudents\",\"url\":\"modules/routes_project.html#getDraftedStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":87,\"kind\":64,\"name\":\"getFreeSpotsFor\",\"url\":\"modules/routes_project.html#getFreeSpotsFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":88,\"kind\":64,\"name\":\"createProjectRoleFor\",\"url\":\"modules/routes_project.html#createProjectRoleFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":89,\"kind\":64,\"name\":\"modProjectStudent\",\"url\":\"modules/routes_project.html#modProjectStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":90,\"kind\":64,\"name\":\"unAssignCoach\",\"url\":\"modules/routes_project.html#unAssignCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":91,\"kind\":64,\"name\":\"assignCoach\",\"url\":\"modules/routes_project.html#assignCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":92,\"kind\":64,\"name\":\"unAssignStudent\",\"url\":\"modules/routes_project.html#unAssignStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":93,\"kind\":64,\"name\":\"assignStudent\",\"url\":\"modules/routes_project.html#assignStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":94,\"kind\":64,\"name\":\"filterProjects\",\"url\":\"modules/routes_project.html#filterProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":95,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_project.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/project\"},{\"id\":96,\"kind\":2,\"name\":\"routes/reset\",\"url\":\"modules/routes_reset.html\",\"classes\":\"tsd-kind-module\"},{\"id\":97,\"kind\":64,\"name\":\"sendMail\",\"url\":\"modules/routes_reset.html#sendMail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":98,\"kind\":64,\"name\":\"requestReset\",\"url\":\"modules/routes_reset.html#requestReset\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":99,\"kind\":64,\"name\":\"checkCode\",\"url\":\"modules/routes_reset.html#checkCode\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":100,\"kind\":64,\"name\":\"resetPassword\",\"url\":\"modules/routes_reset.html#resetPassword\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":101,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_reset.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":102,\"kind\":64,\"name\":\"createEmail\",\"url\":\"modules/routes_reset.html#createEmail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/reset\"},{\"id\":103,\"kind\":2,\"name\":\"routes/role\",\"url\":\"modules/routes_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":104,\"kind\":64,\"name\":\"listStudentRoles\",\"url\":\"modules/routes_role.html#listStudentRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/role\"},{\"id\":105,\"kind\":64,\"name\":\"createStudentRole\",\"url\":\"modules/routes_role.html#createStudentRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/role\"},{\"id\":106,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_role.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/role\"},{\"id\":107,\"kind\":2,\"name\":\"routes/student\",\"url\":\"modules/routes_student.html\",\"classes\":\"tsd-kind-module\"},{\"id\":108,\"kind\":64,\"name\":\"getStudent\",\"url\":\"modules/routes_student.html#getStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":109,\"kind\":64,\"name\":\"deleteStudent\",\"url\":\"modules/routes_student.html#deleteStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":110,\"kind\":64,\"name\":\"createStudentSuggestion\",\"url\":\"modules/routes_student.html#createStudentSuggestion\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":111,\"kind\":64,\"name\":\"getStudentSuggestions\",\"url\":\"modules/routes_student.html#getStudentSuggestions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":112,\"kind\":64,\"name\":\"createStudentConfirmation\",\"url\":\"modules/routes_student.html#createStudentConfirmation\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":113,\"kind\":64,\"name\":\"filterStudents\",\"url\":\"modules/routes_student.html#filterStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":114,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_student.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/student\"},{\"id\":115,\"kind\":2,\"name\":\"routes/template\",\"url\":\"modules/routes_template.html\",\"classes\":\"tsd-kind-module\"},{\"id\":116,\"kind\":64,\"name\":\"getAllTemplates\",\"url\":\"modules/routes_template.html#getAllTemplates\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":117,\"kind\":64,\"name\":\"getSingleTemplate\",\"url\":\"modules/routes_template.html#getSingleTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":118,\"kind\":64,\"name\":\"createTemplate\",\"url\":\"modules/routes_template.html#createTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":119,\"kind\":64,\"name\":\"updateTemplate\",\"url\":\"modules/routes_template.html#updateTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":120,\"kind\":64,\"name\":\"deleteTemplate\",\"url\":\"modules/routes_template.html#deleteTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":121,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_template.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":122,\"kind\":32,\"name\":\"notOwnerError\",\"url\":\"modules/routes_template.html#notOwnerError\",\"classes\":\"tsd-kind-variable tsd-parent-kind-module\",\"parent\":\"routes/template\"},{\"id\":123,\"kind\":2,\"name\":\"routes/user\",\"url\":\"modules/routes_user.html\",\"classes\":\"tsd-kind-module\"},{\"id\":124,\"kind\":64,\"name\":\"listUsers\",\"url\":\"modules/routes_user.html#listUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":125,\"kind\":64,\"name\":\"createUserRequest\",\"url\":\"modules/routes_user.html#createUserRequest\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":126,\"kind\":64,\"name\":\"setAccountStatus\",\"url\":\"modules/routes_user.html#setAccountStatus\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":127,\"kind\":64,\"name\":\"createUserAcceptance\",\"url\":\"modules/routes_user.html#createUserAcceptance\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":128,\"kind\":64,\"name\":\"deleteUserRequest\",\"url\":\"modules/routes_user.html#deleteUserRequest\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":129,\"kind\":64,\"name\":\"filterUsers\",\"url\":\"modules/routes_user.html#filterUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":130,\"kind\":64,\"name\":\"userModSelf\",\"url\":\"modules/routes_user.html#userModSelf\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":131,\"kind\":64,\"name\":\"getCurrentUser\",\"url\":\"modules/routes_user.html#getCurrentUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":132,\"kind\":64,\"name\":\"createUserPermission\",\"url\":\"modules/routes_user.html#createUserPermission\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":133,\"kind\":64,\"name\":\"deleteUserPermission\",\"url\":\"modules/routes_user.html#deleteUserPermission\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":134,\"kind\":64,\"name\":\"getYearPermissions\",\"url\":\"modules/routes_user.html#getYearPermissions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":135,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_user.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/user\"},{\"id\":136,\"kind\":2,\"name\":\"routes/verify\",\"url\":\"modules/routes_verify.html\",\"classes\":\"tsd-kind-module\"},{\"id\":137,\"kind\":64,\"name\":\"verifyKey\",\"url\":\"modules/routes_verify.html#verifyKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/verify\"},{\"id\":138,\"kind\":64,\"name\":\"getRouter\",\"url\":\"modules/routes_verify.html#getRouter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"routes/verify\"},{\"id\":139,\"kind\":2,\"name\":\"orm_functions/applied_role\",\"url\":\"modules/orm_functions_applied_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":140,\"kind\":64,\"name\":\"createAppliedRole\",\"url\":\"modules/orm_functions_applied_role.html#createAppliedRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/applied_role\"},{\"id\":141,\"kind\":64,\"name\":\"getAppliedRolesByJobApplication\",\"url\":\"modules/orm_functions_applied_role.html#getAppliedRolesByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/applied_role\"},{\"id\":142,\"kind\":64,\"name\":\"deleteAppliedRolesByJobApplication\",\"url\":\"modules/orm_functions_applied_role.html#deleteAppliedRolesByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/applied_role\"},{\"id\":143,\"kind\":2,\"name\":\"orm_functions/attachment\",\"url\":\"modules/orm_functions_attachment.html\",\"classes\":\"tsd-kind-module\"},{\"id\":144,\"kind\":64,\"name\":\"createAttachment\",\"url\":\"modules/orm_functions_attachment.html#createAttachment\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":145,\"kind\":64,\"name\":\"deleteAttachment\",\"url\":\"modules/orm_functions_attachment.html#deleteAttachment\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":146,\"kind\":64,\"name\":\"deleteAllAttachmentsForApplication\",\"url\":\"modules/orm_functions_attachment.html#deleteAllAttachmentsForApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":147,\"kind\":64,\"name\":\"getAttachmentById\",\"url\":\"modules/orm_functions_attachment.html#getAttachmentById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/attachment\"},{\"id\":148,\"kind\":2,\"name\":\"orm_functions/contract\",\"url\":\"modules/orm_functions_contract.html\",\"classes\":\"tsd-kind-module\"},{\"id\":149,\"kind\":64,\"name\":\"createContract\",\"url\":\"modules/orm_functions_contract.html#createContract\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":150,\"kind\":64,\"name\":\"updateContract\",\"url\":\"modules/orm_functions_contract.html#updateContract\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":151,\"kind\":64,\"name\":\"removeContractsFromStudent\",\"url\":\"modules/orm_functions_contract.html#removeContractsFromStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":152,\"kind\":64,\"name\":\"removeContract\",\"url\":\"modules/orm_functions_contract.html#removeContract\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":153,\"kind\":64,\"name\":\"contractsForStudent\",\"url\":\"modules/orm_functions_contract.html#contractsForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":154,\"kind\":64,\"name\":\"contractsByProject\",\"url\":\"modules/orm_functions_contract.html#contractsByProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":155,\"kind\":64,\"name\":\"sortedContractsByOsocEdition\",\"url\":\"modules/orm_functions_contract.html#sortedContractsByOsocEdition\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/contract\"},{\"id\":156,\"kind\":2,\"name\":\"orm_functions/evaluation\",\"url\":\"modules/orm_functions_evaluation.html\",\"classes\":\"tsd-kind-module\"},{\"id\":157,\"kind\":64,\"name\":\"checkIfFinalEvaluationExists\",\"url\":\"modules/orm_functions_evaluation.html#checkIfFinalEvaluationExists\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":158,\"kind\":64,\"name\":\"createEvaluationForStudent\",\"url\":\"modules/orm_functions_evaluation.html#createEvaluationForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":159,\"kind\":64,\"name\":\"updateEvaluationForStudent\",\"url\":\"modules/orm_functions_evaluation.html#updateEvaluationForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":160,\"kind\":64,\"name\":\"getLoginUserByEvaluationId\",\"url\":\"modules/orm_functions_evaluation.html#getLoginUserByEvaluationId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":161,\"kind\":64,\"name\":\"getEvaluationByPartiesFor\",\"url\":\"modules/orm_functions_evaluation.html#getEvaluationByPartiesFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":162,\"kind\":64,\"name\":\"deleteEvaluationsByJobApplication\",\"url\":\"modules/orm_functions_evaluation.html#deleteEvaluationsByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/evaluation\"},{\"id\":163,\"kind\":2,\"name\":\"orm_functions/general_purpose\",\"url\":\"modules/orm_functions_general_purpose.html\",\"classes\":\"tsd-kind-module\"},{\"id\":164,\"kind\":64,\"name\":\"addStudentToProject\",\"url\":\"modules/orm_functions_general_purpose.html#addStudentToProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/general_purpose\"},{\"id\":165,\"kind\":2,\"name\":\"orm_functions/job_application_skill\",\"url\":\"modules/orm_functions_job_application_skill.html\",\"classes\":\"tsd-kind-module\"},{\"id\":166,\"kind\":64,\"name\":\"createJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#createJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":167,\"kind\":64,\"name\":\"getAllJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#getAllJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":168,\"kind\":64,\"name\":\"getAllJobApplicationSkillByJobApplication\",\"url\":\"modules/orm_functions_job_application_skill.html#getAllJobApplicationSkillByJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":169,\"kind\":64,\"name\":\"getJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#getJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":170,\"kind\":64,\"name\":\"updateJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#updateJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":171,\"kind\":64,\"name\":\"deleteJobApplicationSkill\",\"url\":\"modules/orm_functions_job_application_skill.html#deleteJobApplicationSkill\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":172,\"kind\":64,\"name\":\"deleteSkillsByJobApplicationId\",\"url\":\"modules/orm_functions_job_application_skill.html#deleteSkillsByJobApplicationId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application_skill\"},{\"id\":173,\"kind\":2,\"name\":\"orm_functions/job_application\",\"url\":\"modules/orm_functions_job_application.html\",\"classes\":\"tsd-kind-module\"},{\"id\":174,\"kind\":64,\"name\":\"getStudentEvaluationsTotal\",\"url\":\"modules/orm_functions_job_application.html#getStudentEvaluationsTotal\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":175,\"kind\":64,\"name\":\"getStudentEvaluationsFinal\",\"url\":\"modules/orm_functions_job_application.html#getStudentEvaluationsFinal\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":176,\"kind\":64,\"name\":\"getStudentEvaluationsTemp\",\"url\":\"modules/orm_functions_job_application.html#getStudentEvaluationsTemp\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":177,\"kind\":64,\"name\":\"getLatestApplicationRolesForStudent\",\"url\":\"modules/orm_functions_job_application.html#getLatestApplicationRolesForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":178,\"kind\":64,\"name\":\"deleteJobApplicationsFromStudent\",\"url\":\"modules/orm_functions_job_application.html#deleteJobApplicationsFromStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":179,\"kind\":64,\"name\":\"changeEmailStatusOfJobApplication\",\"url\":\"modules/orm_functions_job_application.html#changeEmailStatusOfJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":180,\"kind\":64,\"name\":\"deleteJobApplication\",\"url\":\"modules/orm_functions_job_application.html#deleteJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":181,\"kind\":64,\"name\":\"createJobApplication\",\"url\":\"modules/orm_functions_job_application.html#createJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":182,\"kind\":64,\"name\":\"getLatestJobApplicationOfStudent\",\"url\":\"modules/orm_functions_job_application.html#getLatestJobApplicationOfStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":183,\"kind\":64,\"name\":\"getJobApplication\",\"url\":\"modules/orm_functions_job_application.html#getJobApplication\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":184,\"kind\":64,\"name\":\"getJobApplicationByYear\",\"url\":\"modules/orm_functions_job_application.html#getJobApplicationByYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":185,\"kind\":64,\"name\":\"getJobApplicationByYearForStudent\",\"url\":\"modules/orm_functions_job_application.html#getJobApplicationByYearForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":186,\"kind\":64,\"name\":\"getEvaluationsByYearForStudent\",\"url\":\"modules/orm_functions_job_application.html#getEvaluationsByYearForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/job_application\"},{\"id\":187,\"kind\":2,\"name\":\"orm_functions/language\",\"url\":\"modules/orm_functions_language.html\",\"classes\":\"tsd-kind-module\"},{\"id\":188,\"kind\":64,\"name\":\"createLanguage\",\"url\":\"modules/orm_functions_language.html#createLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":189,\"kind\":64,\"name\":\"getAllLanguages\",\"url\":\"modules/orm_functions_language.html#getAllLanguages\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":190,\"kind\":64,\"name\":\"getLanguage\",\"url\":\"modules/orm_functions_language.html#getLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":191,\"kind\":64,\"name\":\"getLanguageByName\",\"url\":\"modules/orm_functions_language.html#getLanguageByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":192,\"kind\":64,\"name\":\"updateLanguage\",\"url\":\"modules/orm_functions_language.html#updateLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":193,\"kind\":64,\"name\":\"deleteLanguage\",\"url\":\"modules/orm_functions_language.html#deleteLanguage\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":194,\"kind\":64,\"name\":\"deleteLanguageByName\",\"url\":\"modules/orm_functions_language.html#deleteLanguageByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/language\"},{\"id\":195,\"kind\":2,\"name\":\"orm_functions/login_user_osoc\",\"url\":\"modules/orm_functions_login_user_osoc.html\",\"classes\":\"tsd-kind-module\"},{\"id\":196,\"kind\":64,\"name\":\"getLoginUserOsocByIds\",\"url\":\"modules/orm_functions_login_user_osoc.html#getLoginUserOsocByIds\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user_osoc\"},{\"id\":197,\"kind\":64,\"name\":\"addOsocToUser\",\"url\":\"modules/orm_functions_login_user_osoc.html#addOsocToUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user_osoc\"},{\"id\":198,\"kind\":64,\"name\":\"deleteOsocsForLoginuser\",\"url\":\"modules/orm_functions_login_user_osoc.html#deleteOsocsForLoginuser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user_osoc\"},{\"id\":199,\"kind\":64,\"name\":\"deleteOsocsLoginConnectionFromOsoc\",\"url\":\"modules/orm_functions_login_user_osoc.html#deleteOsocsLoginConnectionFromOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user_osoc\"},{\"id\":200,\"kind\":64,\"name\":\"removeOsocFromUser\",\"url\":\"modules/orm_functions_login_user_osoc.html#removeOsocFromUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user_osoc\"},{\"id\":201,\"kind\":64,\"name\":\"getOsocYearsForLoginUserById\",\"url\":\"modules/orm_functions_login_user_osoc.html#getOsocYearsForLoginUserById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user_osoc\"},{\"id\":202,\"kind\":2,\"name\":\"orm_functions/login_user\",\"url\":\"modules/orm_functions_login_user.html\",\"classes\":\"tsd-kind-module\"},{\"id\":203,\"kind\":64,\"name\":\"createLoginUser\",\"url\":\"modules/orm_functions_login_user.html#createLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":204,\"kind\":64,\"name\":\"getAllLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#getAllLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":205,\"kind\":64,\"name\":\"getPasswordLoginUserByPerson\",\"url\":\"modules/orm_functions_login_user.html#getPasswordLoginUserByPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":206,\"kind\":64,\"name\":\"getPasswordLoginUser\",\"url\":\"modules/orm_functions_login_user.html#getPasswordLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":207,\"kind\":64,\"name\":\"searchLoginUserByPerson\",\"url\":\"modules/orm_functions_login_user.html#searchLoginUserByPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":208,\"kind\":64,\"name\":\"searchAllAdminLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#searchAllAdminLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":209,\"kind\":64,\"name\":\"searchAllCoachLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#searchAllCoachLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":210,\"kind\":64,\"name\":\"searchAllAdminAndCoachLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#searchAllAdminAndCoachLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":211,\"kind\":64,\"name\":\"updateLoginUser\",\"url\":\"modules/orm_functions_login_user.html#updateLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":212,\"kind\":64,\"name\":\"deleteLoginUserById\",\"url\":\"modules/orm_functions_login_user.html#deleteLoginUserById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":213,\"kind\":64,\"name\":\"deleteLoginUserByPersonId\",\"url\":\"modules/orm_functions_login_user.html#deleteLoginUserByPersonId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":214,\"kind\":64,\"name\":\"deleteLoginUserFromDB\",\"url\":\"modules/orm_functions_login_user.html#deleteLoginUserFromDB\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":215,\"kind\":64,\"name\":\"getLoginUserById\",\"url\":\"modules/orm_functions_login_user.html#getLoginUserById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":216,\"kind\":64,\"name\":\"filterLoginUsers\",\"url\":\"modules/orm_functions_login_user.html#filterLoginUsers\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":217,\"kind\":64,\"name\":\"setCoach\",\"url\":\"modules/orm_functions_login_user.html#setCoach\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":218,\"kind\":64,\"name\":\"setAdmin\",\"url\":\"modules/orm_functions_login_user.html#setAdmin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":219,\"kind\":64,\"name\":\"getOsocYearsForLoginUser\",\"url\":\"modules/orm_functions_login_user.html#getOsocYearsForLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/login_user\"},{\"id\":220,\"kind\":2,\"name\":\"orm_functions/orm_types\",\"url\":\"modules/orm_functions_orm_types.html\",\"classes\":\"tsd-kind-module\"},{\"id\":221,\"kind\":256,\"name\":\"DBPagination\",\"url\":\"interfaces/orm_functions_orm_types.DBPagination.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":222,\"kind\":1024,\"name\":\"currentPage\",\"url\":\"interfaces/orm_functions_orm_types.DBPagination.html#currentPage\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.DBPagination\"},{\"id\":223,\"kind\":1024,\"name\":\"pageSize\",\"url\":\"interfaces/orm_functions_orm_types.DBPagination.html#pageSize\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.DBPagination\"},{\"id\":224,\"kind\":256,\"name\":\"CreatePerson\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":225,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":226,\"kind\":1024,\"name\":\"github\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#github\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":227,\"kind\":1024,\"name\":\"email\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#email\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":228,\"kind\":1024,\"name\":\"github_id\",\"url\":\"interfaces/orm_functions_orm_types.CreatePerson.html#github_id\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreatePerson\"},{\"id\":229,\"kind\":256,\"name\":\"UpdatePerson\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":230,\"kind\":1024,\"name\":\"personId\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#personId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":231,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":232,\"kind\":1024,\"name\":\"github\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#github\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":233,\"kind\":1024,\"name\":\"email\",\"url\":\"interfaces/orm_functions_orm_types.UpdatePerson.html#email\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdatePerson\"},{\"id\":234,\"kind\":256,\"name\":\"CreateLoginUser\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":235,\"kind\":1024,\"name\":\"personId\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#personId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":236,\"kind\":1024,\"name\":\"password\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#password\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":237,\"kind\":1024,\"name\":\"isAdmin\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#isAdmin\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":238,\"kind\":1024,\"name\":\"isCoach\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#isCoach\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":239,\"kind\":1024,\"name\":\"accountStatus\",\"url\":\"interfaces/orm_functions_orm_types.CreateLoginUser.html#accountStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateLoginUser\"},{\"id\":240,\"kind\":256,\"name\":\"UpdateLoginUser\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":241,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":242,\"kind\":1024,\"name\":\"password\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#password\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":243,\"kind\":1024,\"name\":\"isAdmin\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#isAdmin\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":244,\"kind\":1024,\"name\":\"isCoach\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#isCoach\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":245,\"kind\":1024,\"name\":\"accountStatus\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLoginUser.html#accountStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLoginUser\"},{\"id\":246,\"kind\":256,\"name\":\"CreateStudent\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":247,\"kind\":1024,\"name\":\"personId\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#personId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":248,\"kind\":1024,\"name\":\"gender\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#gender\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":249,\"kind\":1024,\"name\":\"pronouns\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#pronouns\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":250,\"kind\":1024,\"name\":\"phoneNumber\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#phoneNumber\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":251,\"kind\":1024,\"name\":\"nickname\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#nickname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":252,\"kind\":1024,\"name\":\"alumni\",\"url\":\"interfaces/orm_functions_orm_types.CreateStudent.html#alumni\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateStudent\"},{\"id\":253,\"kind\":256,\"name\":\"UpdateStudent\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":254,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":255,\"kind\":1024,\"name\":\"gender\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#gender\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":256,\"kind\":1024,\"name\":\"pronouns\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#pronouns\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":257,\"kind\":1024,\"name\":\"phoneNumber\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#phoneNumber\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":258,\"kind\":1024,\"name\":\"nickname\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#nickname\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":259,\"kind\":1024,\"name\":\"alumni\",\"url\":\"interfaces/orm_functions_orm_types.UpdateStudent.html#alumni\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateStudent\"},{\"id\":260,\"kind\":256,\"name\":\"CreateEvaluationForStudent\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":261,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":262,\"kind\":1024,\"name\":\"jobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#jobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":263,\"kind\":1024,\"name\":\"decision\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#decision\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":264,\"kind\":1024,\"name\":\"motivation\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#motivation\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":265,\"kind\":1024,\"name\":\"isFinal\",\"url\":\"interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html#isFinal\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateEvaluationForStudent\"},{\"id\":266,\"kind\":256,\"name\":\"UpdateEvaluationForStudent\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":267,\"kind\":1024,\"name\":\"evaluation_id\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#evaluation_id\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":268,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":269,\"kind\":1024,\"name\":\"decision\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#decision\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":270,\"kind\":1024,\"name\":\"motivation\",\"url\":\"interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html#motivation\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateEvaluationForStudent\"},{\"id\":271,\"kind\":256,\"name\":\"CreateContract\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":272,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":273,\"kind\":1024,\"name\":\"projectRoleId\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#projectRoleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":274,\"kind\":1024,\"name\":\"information\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#information\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":275,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":276,\"kind\":1024,\"name\":\"contractStatus\",\"url\":\"interfaces/orm_functions_orm_types.CreateContract.html#contractStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateContract\"},{\"id\":277,\"kind\":256,\"name\":\"UpdateContract\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":278,\"kind\":1024,\"name\":\"contractId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#contractId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":279,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":280,\"kind\":1024,\"name\":\"information\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#information\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":281,\"kind\":1024,\"name\":\"contractStatus\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#contractStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":282,\"kind\":1024,\"name\":\"projectRoleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateContract.html#projectRoleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateContract\"},{\"id\":283,\"kind\":256,\"name\":\"CreateJobApplication\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":284,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":285,\"kind\":1024,\"name\":\"responsibilities\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#responsibilities\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":286,\"kind\":1024,\"name\":\"funFact\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#funFact\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":287,\"kind\":1024,\"name\":\"studentVolunteerInfo\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#studentVolunteerInfo\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":288,\"kind\":1024,\"name\":\"studentCoach\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#studentCoach\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":289,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":290,\"kind\":1024,\"name\":\"edus\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#edus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":291,\"kind\":1024,\"name\":\"eduLevel\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduLevel\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":292,\"kind\":1024,\"name\":\"eduDuration\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduDuration\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":293,\"kind\":1024,\"name\":\"eduYear\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduYear\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":294,\"kind\":1024,\"name\":\"eduInstitute\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#eduInstitute\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":295,\"kind\":1024,\"name\":\"emailStatus\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#emailStatus\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":296,\"kind\":1024,\"name\":\"createdAt\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplication.html#createdAt\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplication\"},{\"id\":297,\"kind\":256,\"name\":\"UpdateOsoc\",\"url\":\"interfaces/orm_functions_orm_types.UpdateOsoc.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":298,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateOsoc.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateOsoc\"},{\"id\":299,\"kind\":1024,\"name\":\"year\",\"url\":\"interfaces/orm_functions_orm_types.UpdateOsoc.html#year\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateOsoc\"},{\"id\":300,\"kind\":256,\"name\":\"CreateProject\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":301,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":302,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":303,\"kind\":1024,\"name\":\"partner\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#partner\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":304,\"kind\":1024,\"name\":\"startDate\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#startDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":305,\"kind\":1024,\"name\":\"endDate\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#endDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":306,\"kind\":1024,\"name\":\"description\",\"url\":\"interfaces/orm_functions_orm_types.CreateProject.html#description\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProject\"},{\"id\":307,\"kind\":256,\"name\":\"UpdateProject\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":308,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":309,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":310,\"kind\":1024,\"name\":\"osocId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#osocId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":311,\"kind\":1024,\"name\":\"partner\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#partner\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":312,\"kind\":1024,\"name\":\"startDate\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#startDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":313,\"kind\":1024,\"name\":\"endDate\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#endDate\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":314,\"kind\":1024,\"name\":\"description\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProject.html#description\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProject\"},{\"id\":315,\"kind\":256,\"name\":\"FilterProjects\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":316,\"kind\":1024,\"name\":\"project_id\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#project_id\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":317,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":318,\"kind\":1024,\"name\":\"osoc_id\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#osoc_id\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":319,\"kind\":1024,\"name\":\"partner\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#partner\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":320,\"kind\":1024,\"name\":\"start_date\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#start_date\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":321,\"kind\":1024,\"name\":\"end_date\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#end_date\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":322,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":323,\"kind\":1024,\"name\":\"description\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#description\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":324,\"kind\":1024,\"name\":\"project_role\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#project_role\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":325,\"kind\":1024,\"name\":\"project_user\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjects.html#project_user\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjects\"},{\"id\":326,\"kind\":256,\"name\":\"FilterProjectsRole\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":327,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjectsRole\"},{\"id\":328,\"kind\":1024,\"name\":\"role\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html#role\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjectsRole\"},{\"id\":329,\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html#__type-1\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjectsRole\"},{\"id\":330,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html#__type-1.name\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"orm_functions/orm_types.FilterProjectsRole.__type\"},{\"id\":331,\"kind\":1024,\"name\":\"_count\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html#_count\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjectsRole\"},{\"id\":332,\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjectsRole\"},{\"id\":333,\"kind\":1024,\"name\":\"contract\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsRole.html#__type.contract\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"orm_functions/orm_types.FilterProjectsRole.__type\"},{\"id\":334,\"kind\":256,\"name\":\"FilterProjectsLoginUser\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":335,\"kind\":1024,\"name\":\"login_user\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html#login_user\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjectsLoginUser\"},{\"id\":336,\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.FilterProjectsLoginUser\"},{\"id\":337,\"kind\":1024,\"name\":\"login_user_id\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html#__type.login_user_id\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"orm_functions/orm_types.FilterProjectsLoginUser.__type\"},{\"id\":338,\"kind\":1024,\"name\":\"is_coach\",\"url\":\"interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html#__type.is_coach\",\"classes\":\"tsd-kind-property tsd-parent-kind-type-literal\",\"parent\":\"orm_functions/orm_types.FilterProjectsLoginUser.__type\"},{\"id\":339,\"kind\":256,\"name\":\"CreateProjectRole\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":340,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectRole\"},{\"id\":341,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectRole\"},{\"id\":342,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.CreateProjectRole.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateProjectRole\"},{\"id\":343,\"kind\":256,\"name\":\"UpdateProjectRole\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":344,\"kind\":1024,\"name\":\"projectRoleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#projectRoleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":345,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":346,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":347,\"kind\":1024,\"name\":\"positions\",\"url\":\"interfaces/orm_functions_orm_types.UpdateProjectRole.html#positions\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateProjectRole\"},{\"id\":348,\"kind\":256,\"name\":\"UpdateRole\",\"url\":\"interfaces/orm_functions_orm_types.UpdateRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":349,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateRole\"},{\"id\":350,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateRole.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateRole\"},{\"id\":351,\"kind\":256,\"name\":\"UpdateLanguage\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLanguage.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":352,\"kind\":1024,\"name\":\"languageId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLanguage.html#languageId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLanguage\"},{\"id\":353,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateLanguage.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateLanguage\"},{\"id\":354,\"kind\":256,\"name\":\"CreateJobApplicationSkill\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":355,\"kind\":1024,\"name\":\"jobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#jobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":356,\"kind\":1024,\"name\":\"skill\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#skill\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":357,\"kind\":1024,\"name\":\"languageId\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#languageId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":358,\"kind\":1024,\"name\":\"level\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#level\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":359,\"kind\":1024,\"name\":\"isPreferred\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#isPreferred\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":360,\"kind\":1024,\"name\":\"isBest\",\"url\":\"interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html#isBest\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateJobApplicationSkill\"},{\"id\":361,\"kind\":256,\"name\":\"UpdateJobApplicationSkill\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":362,\"kind\":1024,\"name\":\"JobApplicationSkillId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#JobApplicationSkillId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":363,\"kind\":1024,\"name\":\"JobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#JobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":364,\"kind\":1024,\"name\":\"skill\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#skill\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":365,\"kind\":1024,\"name\":\"languageId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#languageId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":366,\"kind\":1024,\"name\":\"level\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#level\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":367,\"kind\":1024,\"name\":\"isPreferred\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#isPreferred\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":368,\"kind\":1024,\"name\":\"is_best\",\"url\":\"interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html#is_best\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateJobApplicationSkill\"},{\"id\":369,\"kind\":256,\"name\":\"AddStudentToProject\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":370,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":371,\"kind\":1024,\"name\":\"studentId\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#studentId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":372,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":373,\"kind\":1024,\"name\":\"roleName\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#roleName\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":374,\"kind\":1024,\"name\":\"information\",\"url\":\"interfaces/orm_functions_orm_types.AddStudentToProject.html#information\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.AddStudentToProject\"},{\"id\":375,\"kind\":256,\"name\":\"ProjectUser\",\"url\":\"interfaces/orm_functions_orm_types.ProjectUser.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":376,\"kind\":1024,\"name\":\"projectId\",\"url\":\"interfaces/orm_functions_orm_types.ProjectUser.html#projectId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.ProjectUser\"},{\"id\":377,\"kind\":1024,\"name\":\"loginUserId\",\"url\":\"interfaces/orm_functions_orm_types.ProjectUser.html#loginUserId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.ProjectUser\"},{\"id\":378,\"kind\":256,\"name\":\"CreateAppliedRole\",\"url\":\"interfaces/orm_functions_orm_types.CreateAppliedRole.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":379,\"kind\":1024,\"name\":\"jobApplicationId\",\"url\":\"interfaces/orm_functions_orm_types.CreateAppliedRole.html#jobApplicationId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateAppliedRole\"},{\"id\":380,\"kind\":1024,\"name\":\"roleId\",\"url\":\"interfaces/orm_functions_orm_types.CreateAppliedRole.html#roleId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateAppliedRole\"},{\"id\":381,\"kind\":256,\"name\":\"CreateTemplate\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":382,\"kind\":1024,\"name\":\"ownerId\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#ownerId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":383,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":384,\"kind\":1024,\"name\":\"content\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#content\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":385,\"kind\":1024,\"name\":\"subject\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#subject\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":386,\"kind\":1024,\"name\":\"cc\",\"url\":\"interfaces/orm_functions_orm_types.CreateTemplate.html#cc\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.CreateTemplate\"},{\"id\":387,\"kind\":256,\"name\":\"UpdateTemplate\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":388,\"kind\":1024,\"name\":\"templateId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#templateId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":389,\"kind\":1024,\"name\":\"ownerId\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#ownerId\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":390,\"kind\":1024,\"name\":\"name\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#name\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":391,\"kind\":1024,\"name\":\"content\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#content\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":392,\"kind\":1024,\"name\":\"subject\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#subject\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":393,\"kind\":1024,\"name\":\"cc\",\"url\":\"interfaces/orm_functions_orm_types.UpdateTemplate.html#cc\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"orm_functions/orm_types.UpdateTemplate\"},{\"id\":394,\"kind\":4194304,\"name\":\"FilterSort\",\"url\":\"modules/orm_functions_orm_types.html#FilterSort\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":395,\"kind\":4194304,\"name\":\"FilterString\",\"url\":\"modules/orm_functions_orm_types.html#FilterString\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":396,\"kind\":4194304,\"name\":\"FilterNumber\",\"url\":\"modules/orm_functions_orm_types.html#FilterNumber\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":397,\"kind\":4194304,\"name\":\"FilterNumberArray\",\"url\":\"modules/orm_functions_orm_types.html#FilterNumberArray\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":398,\"kind\":4194304,\"name\":\"FilterStringArray\",\"url\":\"modules/orm_functions_orm_types.html#FilterStringArray\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":399,\"kind\":4194304,\"name\":\"FilterBoolean\",\"url\":\"modules/orm_functions_orm_types.html#FilterBoolean\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"orm_functions/orm_types\"},{\"id\":400,\"kind\":2,\"name\":\"orm_functions/osoc\",\"url\":\"modules/orm_functions_osoc.html\",\"classes\":\"tsd-kind-module\"},{\"id\":401,\"kind\":64,\"name\":\"createOsoc\",\"url\":\"modules/orm_functions_osoc.html#createOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":402,\"kind\":64,\"name\":\"getAllOsoc\",\"url\":\"modules/orm_functions_osoc.html#getAllOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":403,\"kind\":64,\"name\":\"getLatestOsoc\",\"url\":\"modules/orm_functions_osoc.html#getLatestOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":404,\"kind\":64,\"name\":\"getOsocByYear\",\"url\":\"modules/orm_functions_osoc.html#getOsocByYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":405,\"kind\":64,\"name\":\"getOsocBeforeYear\",\"url\":\"modules/orm_functions_osoc.html#getOsocBeforeYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":406,\"kind\":64,\"name\":\"getOsocAfterYear\",\"url\":\"modules/orm_functions_osoc.html#getOsocAfterYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":407,\"kind\":64,\"name\":\"updateOsoc\",\"url\":\"modules/orm_functions_osoc.html#updateOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":408,\"kind\":64,\"name\":\"deleteOsoc\",\"url\":\"modules/orm_functions_osoc.html#deleteOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":409,\"kind\":64,\"name\":\"deleteOsocByYear\",\"url\":\"modules/orm_functions_osoc.html#deleteOsocByYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":410,\"kind\":64,\"name\":\"deleteOsocFromDB\",\"url\":\"modules/orm_functions_osoc.html#deleteOsocFromDB\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":411,\"kind\":64,\"name\":\"getNewestOsoc\",\"url\":\"modules/orm_functions_osoc.html#getNewestOsoc\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":412,\"kind\":64,\"name\":\"filterOsocs\",\"url\":\"modules/orm_functions_osoc.html#filterOsocs\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":413,\"kind\":64,\"name\":\"getOsocById\",\"url\":\"modules/orm_functions_osoc.html#getOsocById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/osoc\"},{\"id\":414,\"kind\":2,\"name\":\"orm_functions/password_reset\",\"url\":\"modules/orm_functions_password_reset.html\",\"classes\":\"tsd-kind-module\"},{\"id\":415,\"kind\":64,\"name\":\"createOrUpdateReset\",\"url\":\"modules/orm_functions_password_reset.html#createOrUpdateReset\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":416,\"kind\":64,\"name\":\"findResetByCode\",\"url\":\"modules/orm_functions_password_reset.html#findResetByCode\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":417,\"kind\":64,\"name\":\"deleteResetWithLoginUser\",\"url\":\"modules/orm_functions_password_reset.html#deleteResetWithLoginUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":418,\"kind\":64,\"name\":\"deleteResetWithResetId\",\"url\":\"modules/orm_functions_password_reset.html#deleteResetWithResetId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/password_reset\"},{\"id\":419,\"kind\":2,\"name\":\"orm_functions/person\",\"url\":\"modules/orm_functions_person.html\",\"classes\":\"tsd-kind-module\"},{\"id\":420,\"kind\":64,\"name\":\"createPerson\",\"url\":\"modules/orm_functions_person.html#createPerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":421,\"kind\":64,\"name\":\"getAllPersons\",\"url\":\"modules/orm_functions_person.html#getAllPersons\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":422,\"kind\":64,\"name\":\"getPasswordPersonByEmail\",\"url\":\"modules/orm_functions_person.html#getPasswordPersonByEmail\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":423,\"kind\":64,\"name\":\"getPasswordPersonByGithub\",\"url\":\"modules/orm_functions_person.html#getPasswordPersonByGithub\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":424,\"kind\":64,\"name\":\"searchPersonByName\",\"url\":\"modules/orm_functions_person.html#searchPersonByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":425,\"kind\":64,\"name\":\"searchPersonByLogin\",\"url\":\"modules/orm_functions_person.html#searchPersonByLogin\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":426,\"kind\":64,\"name\":\"updatePerson\",\"url\":\"modules/orm_functions_person.html#updatePerson\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":427,\"kind\":64,\"name\":\"deletePersonById\",\"url\":\"modules/orm_functions_person.html#deletePersonById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":428,\"kind\":64,\"name\":\"deletePersonFromDB\",\"url\":\"modules/orm_functions_person.html#deletePersonFromDB\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/person\"},{\"id\":429,\"kind\":2,\"name\":\"orm_functions/project_role\",\"url\":\"modules/orm_functions_project_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":430,\"kind\":64,\"name\":\"createProjectRole\",\"url\":\"modules/orm_functions_project_role.html#createProjectRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":431,\"kind\":64,\"name\":\"getProjectRolesByProject\",\"url\":\"modules/orm_functions_project_role.html#getProjectRolesByProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":432,\"kind\":64,\"name\":\"getNumberOfRolesByProjectAndRole\",\"url\":\"modules/orm_functions_project_role.html#getNumberOfRolesByProjectAndRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":433,\"kind\":64,\"name\":\"getProjectRoleNamesByProject\",\"url\":\"modules/orm_functions_project_role.html#getProjectRoleNamesByProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":434,\"kind\":64,\"name\":\"updateProjectRole\",\"url\":\"modules/orm_functions_project_role.html#updateProjectRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":435,\"kind\":64,\"name\":\"deleteProjectRole\",\"url\":\"modules/orm_functions_project_role.html#deleteProjectRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":436,\"kind\":64,\"name\":\"getNumberOfFreePositions\",\"url\":\"modules/orm_functions_project_role.html#getNumberOfFreePositions\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":437,\"kind\":64,\"name\":\"getProjectRoleById\",\"url\":\"modules/orm_functions_project_role.html#getProjectRoleById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_role\"},{\"id\":438,\"kind\":2,\"name\":\"orm_functions/project_user\",\"url\":\"modules/orm_functions_project_user.html\",\"classes\":\"tsd-kind-module\"},{\"id\":439,\"kind\":64,\"name\":\"createProjectUser\",\"url\":\"modules/orm_functions_project_user.html#createProjectUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_user\"},{\"id\":440,\"kind\":64,\"name\":\"getUsersFor\",\"url\":\"modules/orm_functions_project_user.html#getUsersFor\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_user\"},{\"id\":441,\"kind\":64,\"name\":\"deleteProjectUser\",\"url\":\"modules/orm_functions_project_user.html#deleteProjectUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project_user\"},{\"id\":442,\"kind\":2,\"name\":\"orm_functions/project\",\"url\":\"modules/orm_functions_project.html\",\"classes\":\"tsd-kind-module\"},{\"id\":443,\"kind\":64,\"name\":\"createProject\",\"url\":\"modules/orm_functions_project.html#createProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":444,\"kind\":64,\"name\":\"getAllProjects\",\"url\":\"modules/orm_functions_project.html#getAllProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":445,\"kind\":64,\"name\":\"getProjectById\",\"url\":\"modules/orm_functions_project.html#getProjectById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":446,\"kind\":64,\"name\":\"getProjectByName\",\"url\":\"modules/orm_functions_project.html#getProjectByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":447,\"kind\":64,\"name\":\"getProjectsByOsocEdition\",\"url\":\"modules/orm_functions_project.html#getProjectsByOsocEdition\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":448,\"kind\":64,\"name\":\"getProjectsByPartner\",\"url\":\"modules/orm_functions_project.html#getProjectsByPartner\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":449,\"kind\":64,\"name\":\"getProjectsByStartDate\",\"url\":\"modules/orm_functions_project.html#getProjectsByStartDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":450,\"kind\":64,\"name\":\"getProjectsStartedAfterDate\",\"url\":\"modules/orm_functions_project.html#getProjectsStartedAfterDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":451,\"kind\":64,\"name\":\"getProjectsStartedBeforeDate\",\"url\":\"modules/orm_functions_project.html#getProjectsStartedBeforeDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":452,\"kind\":64,\"name\":\"getProjectsByEndDate\",\"url\":\"modules/orm_functions_project.html#getProjectsByEndDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":453,\"kind\":64,\"name\":\"getProjectsEndedAfterDate\",\"url\":\"modules/orm_functions_project.html#getProjectsEndedAfterDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":454,\"kind\":64,\"name\":\"getProjectsEndedBeforeDate\",\"url\":\"modules/orm_functions_project.html#getProjectsEndedBeforeDate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":455,\"kind\":64,\"name\":\"updateProject\",\"url\":\"modules/orm_functions_project.html#updateProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":456,\"kind\":64,\"name\":\"deleteProject\",\"url\":\"modules/orm_functions_project.html#deleteProject\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":457,\"kind\":64,\"name\":\"deleteProjectByOsocEdition\",\"url\":\"modules/orm_functions_project.html#deleteProjectByOsocEdition\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":458,\"kind\":64,\"name\":\"deleteProjectByPartner\",\"url\":\"modules/orm_functions_project.html#deleteProjectByPartner\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":459,\"kind\":64,\"name\":\"filterProjects\",\"url\":\"modules/orm_functions_project.html#filterProjects\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":460,\"kind\":64,\"name\":\"getProjectYear\",\"url\":\"modules/orm_functions_project.html#getProjectYear\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":461,\"kind\":64,\"name\":\"deleteProjectFromDB\",\"url\":\"modules/orm_functions_project.html#deleteProjectFromDB\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/project\"},{\"id\":462,\"kind\":2,\"name\":\"orm_functions/role\",\"url\":\"modules/orm_functions_role.html\",\"classes\":\"tsd-kind-module\"},{\"id\":463,\"kind\":64,\"name\":\"createRole\",\"url\":\"modules/orm_functions_role.html#createRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":464,\"kind\":64,\"name\":\"getAllRoles\",\"url\":\"modules/orm_functions_role.html#getAllRoles\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":465,\"kind\":64,\"name\":\"getRole\",\"url\":\"modules/orm_functions_role.html#getRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":466,\"kind\":64,\"name\":\"getRolesByName\",\"url\":\"modules/orm_functions_role.html#getRolesByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":467,\"kind\":64,\"name\":\"getProjectRoleWithRoleName\",\"url\":\"modules/orm_functions_role.html#getProjectRoleWithRoleName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":468,\"kind\":64,\"name\":\"updateRole\",\"url\":\"modules/orm_functions_role.html#updateRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":469,\"kind\":64,\"name\":\"deleteRole\",\"url\":\"modules/orm_functions_role.html#deleteRole\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":470,\"kind\":64,\"name\":\"deleteRoleByName\",\"url\":\"modules/orm_functions_role.html#deleteRoleByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/role\"},{\"id\":471,\"kind\":2,\"name\":\"orm_functions/session_key\",\"url\":\"modules/orm_functions_session_key.html\",\"classes\":\"tsd-kind-module\"},{\"id\":472,\"kind\":64,\"name\":\"addSessionKey\",\"url\":\"modules/orm_functions_session_key.html#addSessionKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":473,\"kind\":64,\"name\":\"checkSessionKey\",\"url\":\"modules/orm_functions_session_key.html#checkSessionKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":474,\"kind\":64,\"name\":\"refreshKey\",\"url\":\"modules/orm_functions_session_key.html#refreshKey\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":475,\"kind\":64,\"name\":\"removeAllKeysForUser\",\"url\":\"modules/orm_functions_session_key.html#removeAllKeysForUser\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":476,\"kind\":64,\"name\":\"removeAllKeysForLoginUserId\",\"url\":\"modules/orm_functions_session_key.html#removeAllKeysForLoginUserId\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/session_key\"},{\"id\":477,\"kind\":2,\"name\":\"orm_functions/student\",\"url\":\"modules/orm_functions_student.html\",\"classes\":\"tsd-kind-module\"},{\"id\":478,\"kind\":64,\"name\":\"createStudent\",\"url\":\"modules/orm_functions_student.html#createStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":479,\"kind\":64,\"name\":\"getAllStudents\",\"url\":\"modules/orm_functions_student.html#getAllStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":480,\"kind\":64,\"name\":\"getStudent\",\"url\":\"modules/orm_functions_student.html#getStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":481,\"kind\":64,\"name\":\"updateStudent\",\"url\":\"modules/orm_functions_student.html#updateStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":482,\"kind\":64,\"name\":\"deleteStudent\",\"url\":\"modules/orm_functions_student.html#deleteStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":483,\"kind\":64,\"name\":\"deleteStudentFromDB\",\"url\":\"modules/orm_functions_student.html#deleteStudentFromDB\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":484,\"kind\":64,\"name\":\"searchStudentByGender\",\"url\":\"modules/orm_functions_student.html#searchStudentByGender\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":485,\"kind\":64,\"name\":\"filterStudents\",\"url\":\"modules/orm_functions_student.html#filterStudents\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":486,\"kind\":64,\"name\":\"getAppliedYearsForStudent\",\"url\":\"modules/orm_functions_student.html#getAppliedYearsForStudent\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/student\"},{\"id\":487,\"kind\":2,\"name\":\"orm_functions/template\",\"url\":\"modules/orm_functions_template.html\",\"classes\":\"tsd-kind-module\"},{\"id\":488,\"kind\":64,\"name\":\"getAllTemplates\",\"url\":\"modules/orm_functions_template.html#getAllTemplates\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":489,\"kind\":64,\"name\":\"getTemplateById\",\"url\":\"modules/orm_functions_template.html#getTemplateById\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":490,\"kind\":64,\"name\":\"getTemplatesByName\",\"url\":\"modules/orm_functions_template.html#getTemplatesByName\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":491,\"kind\":64,\"name\":\"createTemplate\",\"url\":\"modules/orm_functions_template.html#createTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":492,\"kind\":64,\"name\":\"updateTemplate\",\"url\":\"modules/orm_functions_template.html#updateTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"},{\"id\":493,\"kind\":64,\"name\":\"deleteTemplate\",\"url\":\"modules/orm_functions_template.html#deleteTemplate\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"orm_functions/template\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"parent\"],\"fieldVectors\":[[\"name/0\",[0,44.998]],[\"parent/0\",[]],[\"name/1\",[1,57.991]],[\"parent/1\",[0,4.364]],[\"name/2\",[2,57.991]],[\"parent/2\",[0,4.364]],[\"name/3\",[3,57.991]],[\"parent/3\",[0,4.364]],[\"name/4\",[4,35.304]],[\"parent/4\",[0,4.364]],[\"name/5\",[5,44.998]],[\"parent/5\",[]],[\"name/6\",[6,57.991]],[\"parent/6\",[5,4.364]],[\"name/7\",[7,57.991]],[\"parent/7\",[5,4.364]],[\"name/8\",[8,57.991]],[\"parent/8\",[5,4.364]],[\"name/9\",[4,35.304]],[\"parent/9\",[5,4.364]],[\"name/10\",[9,47.005]],[\"parent/10\",[]],[\"name/11\",[10,57.991]],[\"parent/11\",[9,4.558]],[\"name/12\",[11,57.991]],[\"parent/12\",[9,4.558]],[\"name/13\",[4,35.304]],[\"parent/13\",[9,4.558]],[\"name/14\",[12,24.091]],[\"parent/14\",[]],[\"name/15\",[13,57.991]],[\"parent/15\",[12,2.336]],[\"name/16\",[14,57.991]],[\"parent/16\",[12,2.336]],[\"name/17\",[15,57.991]],[\"parent/17\",[12,2.336]],[\"name/18\",[16,57.991]],[\"parent/18\",[12,2.336]],[\"name/19\",[17,57.991]],[\"parent/19\",[12,2.336]],[\"name/20\",[18,57.991]],[\"parent/20\",[12,2.336]],[\"name/21\",[19,57.991]],[\"parent/21\",[12,2.336]],[\"name/22\",[20,57.991]],[\"parent/22\",[12,2.336]],[\"name/23\",[21,57.991]],[\"parent/23\",[12,2.336]],[\"name/24\",[22,57.991]],[\"parent/24\",[12,2.336]],[\"name/25\",[23,57.991]],[\"parent/25\",[12,2.336]],[\"name/26\",[24,57.991]],[\"parent/26\",[12,2.336]],[\"name/27\",[25,57.991]],[\"parent/27\",[12,2.336]],[\"name/28\",[26,57.991]],[\"parent/28\",[12,2.336]],[\"name/29\",[27,57.991]],[\"parent/29\",[12,2.336]],[\"name/30\",[28,57.991]],[\"parent/30\",[12,2.336]],[\"name/31\",[29,57.991]],[\"parent/31\",[12,2.336]],[\"name/32\",[30,57.991]],[\"parent/32\",[12,2.336]],[\"name/33\",[31,57.991]],[\"parent/33\",[12,2.336]],[\"name/34\",[32,57.991]],[\"parent/34\",[12,2.336]],[\"name/35\",[33,57.991]],[\"parent/35\",[12,2.336]],[\"name/36\",[34,57.991]],[\"parent/36\",[12,2.336]],[\"name/37\",[35,57.991]],[\"parent/37\",[12,2.336]],[\"name/38\",[36,57.991]],[\"parent/38\",[12,2.336]],[\"name/39\",[37,57.991]],[\"parent/39\",[12,2.336]],[\"name/40\",[38,57.991]],[\"parent/40\",[12,2.336]],[\"name/41\",[39,57.991]],[\"parent/41\",[12,2.336]],[\"name/42\",[40,57.991]],[\"parent/42\",[12,2.336]],[\"name/43\",[41,57.991]],[\"parent/43\",[12,2.336]],[\"name/44\",[42,57.991]],[\"parent/44\",[12,2.336]],[\"name/45\",[43,57.991]],[\"parent/45\",[12,2.336]],[\"name/46\",[44,57.991]],[\"parent/46\",[12,2.336]],[\"name/47\",[45,57.991]],[\"parent/47\",[12,2.336]],[\"name/48\",[46,57.991]],[\"parent/48\",[12,2.336]],[\"name/49\",[47,57.991]],[\"parent/49\",[12,2.336]],[\"name/50\",[48,57.991]],[\"parent/50\",[12,2.336]],[\"name/51\",[49,57.991]],[\"parent/51\",[12,2.336]],[\"name/52\",[50,57.991]],[\"parent/52\",[12,2.336]],[\"name/53\",[51,57.991]],[\"parent/53\",[12,2.336]],[\"name/54\",[52,57.991]],[\"parent/54\",[12,2.336]],[\"name/55\",[53,57.991]],[\"parent/55\",[12,2.336]],[\"name/56\",[54,57.991]],[\"parent/56\",[12,2.336]],[\"name/57\",[4,35.304]],[\"parent/57\",[12,2.336]],[\"name/58\",[55,37.622]],[\"parent/58\",[]],[\"name/59\",[56,57.991]],[\"parent/59\",[55,3.648]],[\"name/60\",[57,57.991]],[\"parent/60\",[55,3.648]],[\"name/61\",[58,57.991]],[\"parent/61\",[55,3.648]],[\"name/62\",[59,57.991]],[\"parent/62\",[55,3.648]],[\"name/63\",[60,57.991]],[\"parent/63\",[55,3.648]],[\"name/64\",[61,57.991]],[\"parent/64\",[55,3.648]],[\"name/65\",[62,57.991]],[\"parent/65\",[55,3.648]],[\"name/66\",[63,57.991]],[\"parent/66\",[55,3.648]],[\"name/67\",[4,35.304]],[\"parent/67\",[55,3.648]],[\"name/68\",[64,57.991]],[\"parent/68\",[55,3.648]],[\"name/69\",[65,47.005]],[\"parent/69\",[66,5.624]],[\"name/70\",[67,47.005]],[\"parent/70\",[]],[\"name/71\",[68,57.991]],[\"parent/71\",[67,4.558]],[\"name/72\",[69,57.991]],[\"parent/72\",[67,4.558]],[\"name/73\",[4,35.304]],[\"parent/73\",[67,4.558]],[\"name/74\",[70,43.328]],[\"parent/74\",[]],[\"name/75\",[71,57.991]],[\"parent/75\",[70,4.202]],[\"name/76\",[72,57.991]],[\"parent/76\",[70,4.202]],[\"name/77\",[73,57.991]],[\"parent/77\",[70,4.202]],[\"name/78\",[74,57.991]],[\"parent/78\",[70,4.202]],[\"name/79\",[4,35.304]],[\"parent/79\",[70,4.202]],[\"name/80\",[75,34.012]],[\"parent/80\",[]],[\"name/81\",[76,49.518]],[\"parent/81\",[75,3.298]],[\"name/82\",[77,57.991]],[\"parent/82\",[75,3.298]],[\"name/83\",[78,57.991]],[\"parent/83\",[75,3.298]],[\"name/84\",[79,57.991]],[\"parent/84\",[75,3.298]],[\"name/85\",[80,52.883]],[\"parent/85\",[75,3.298]],[\"name/86\",[81,57.991]],[\"parent/86\",[75,3.298]],[\"name/87\",[82,57.991]],[\"parent/87\",[75,3.298]],[\"name/88\",[83,57.991]],[\"parent/88\",[75,3.298]],[\"name/89\",[84,57.991]],[\"parent/89\",[75,3.298]],[\"name/90\",[85,57.991]],[\"parent/90\",[75,3.298]],[\"name/91\",[86,57.991]],[\"parent/91\",[75,3.298]],[\"name/92\",[87,57.991]],[\"parent/92\",[75,3.298]],[\"name/93\",[88,57.991]],[\"parent/93\",[75,3.298]],[\"name/94\",[89,49.518]],[\"parent/94\",[75,3.298]],[\"name/95\",[4,35.304]],[\"parent/95\",[75,3.298]],[\"name/96\",[90,41.897]],[\"parent/96\",[]],[\"name/97\",[91,57.991]],[\"parent/97\",[90,4.063]],[\"name/98\",[92,57.991]],[\"parent/98\",[90,4.063]],[\"name/99\",[93,57.991]],[\"parent/99\",[90,4.063]],[\"name/100\",[94,57.991]],[\"parent/100\",[90,4.063]],[\"name/101\",[4,35.304]],[\"parent/101\",[90,4.063]],[\"name/102\",[95,57.991]],[\"parent/102\",[90,4.063]],[\"name/103\",[96,47.005]],[\"parent/103\",[]],[\"name/104\",[97,57.991]],[\"parent/104\",[96,4.558]],[\"name/105\",[98,57.991]],[\"parent/105\",[96,4.558]],[\"name/106\",[4,35.304]],[\"parent/106\",[96,4.558]],[\"name/107\",[99,40.645]],[\"parent/107\",[]],[\"name/108\",[100,52.883]],[\"parent/108\",[99,3.942]],[\"name/109\",[101,52.883]],[\"parent/109\",[99,3.942]],[\"name/110\",[102,57.991]],[\"parent/110\",[99,3.942]],[\"name/111\",[103,57.991]],[\"parent/111\",[99,3.942]],[\"name/112\",[104,57.991]],[\"parent/112\",[99,3.942]],[\"name/113\",[105,52.883]],[\"parent/113\",[99,3.942]],[\"name/114\",[4,35.304]],[\"parent/114\",[99,3.942]],[\"name/115\",[106,40.645]],[\"parent/115\",[]],[\"name/116\",[107,52.883]],[\"parent/116\",[106,3.942]],[\"name/117\",[108,57.991]],[\"parent/117\",[106,3.942]],[\"name/118\",[109,49.518]],[\"parent/118\",[106,3.942]],[\"name/119\",[110,49.518]],[\"parent/119\",[106,3.942]],[\"name/120\",[111,52.883]],[\"parent/120\",[106,3.942]],[\"name/121\",[4,35.304]],[\"parent/121\",[106,3.942]],[\"name/122\",[112,57.991]],[\"parent/122\",[106,3.942]],[\"name/123\",[113,36.019]],[\"parent/123\",[]],[\"name/124\",[114,57.991]],[\"parent/124\",[113,3.493]],[\"name/125\",[115,57.991]],[\"parent/125\",[113,3.493]],[\"name/126\",[116,57.991]],[\"parent/126\",[113,3.493]],[\"name/127\",[117,57.991]],[\"parent/127\",[113,3.493]],[\"name/128\",[118,57.991]],[\"parent/128\",[113,3.493]],[\"name/129\",[119,57.991]],[\"parent/129\",[113,3.493]],[\"name/130\",[120,57.991]],[\"parent/130\",[113,3.493]],[\"name/131\",[121,57.991]],[\"parent/131\",[113,3.493]],[\"name/132\",[122,57.991]],[\"parent/132\",[113,3.493]],[\"name/133\",[123,57.991]],[\"parent/133\",[113,3.493]],[\"name/134\",[124,57.991]],[\"parent/134\",[113,3.493]],[\"name/135\",[4,35.304]],[\"parent/135\",[113,3.493]],[\"name/136\",[125,49.518]],[\"parent/136\",[]],[\"name/137\",[126,57.991]],[\"parent/137\",[125,4.802]],[\"name/138\",[4,35.304]],[\"parent/138\",[125,4.802]],[\"name/139\",[127,47.005]],[\"parent/139\",[]],[\"name/140\",[128,52.883]],[\"parent/140\",[127,4.558]],[\"name/141\",[129,57.991]],[\"parent/141\",[127,4.558]],[\"name/142\",[130,57.991]],[\"parent/142\",[127,4.558]],[\"name/143\",[131,44.998]],[\"parent/143\",[]],[\"name/144\",[132,57.991]],[\"parent/144\",[131,4.364]],[\"name/145\",[133,57.991]],[\"parent/145\",[131,4.364]],[\"name/146\",[134,57.991]],[\"parent/146\",[131,4.364]],[\"name/147\",[135,57.991]],[\"parent/147\",[131,4.364]],[\"name/148\",[136,40.645]],[\"parent/148\",[]],[\"name/149\",[137,52.883]],[\"parent/149\",[136,3.942]],[\"name/150\",[138,52.883]],[\"parent/150\",[136,3.942]],[\"name/151\",[139,57.991]],[\"parent/151\",[136,3.942]],[\"name/152\",[140,57.991]],[\"parent/152\",[136,3.942]],[\"name/153\",[141,57.991]],[\"parent/153\",[136,3.942]],[\"name/154\",[142,57.991]],[\"parent/154\",[136,3.942]],[\"name/155\",[143,57.991]],[\"parent/155\",[136,3.942]],[\"name/156\",[144,41.897]],[\"parent/156\",[]],[\"name/157\",[145,57.991]],[\"parent/157\",[144,4.063]],[\"name/158\",[146,52.883]],[\"parent/158\",[144,4.063]],[\"name/159\",[147,52.883]],[\"parent/159\",[144,4.063]],[\"name/160\",[148,57.991]],[\"parent/160\",[144,4.063]],[\"name/161\",[149,57.991]],[\"parent/161\",[144,4.063]],[\"name/162\",[150,57.991]],[\"parent/162\",[144,4.063]],[\"name/163\",[151,52.883]],[\"parent/163\",[]],[\"name/164\",[152,52.883]],[\"parent/164\",[151,5.128]],[\"name/165\",[153,40.645]],[\"parent/165\",[]],[\"name/166\",[154,52.883]],[\"parent/166\",[153,3.942]],[\"name/167\",[155,57.991]],[\"parent/167\",[153,3.942]],[\"name/168\",[156,57.991]],[\"parent/168\",[153,3.942]],[\"name/169\",[157,57.991]],[\"parent/169\",[153,3.942]],[\"name/170\",[158,52.883]],[\"parent/170\",[153,3.942]],[\"name/171\",[159,57.991]],[\"parent/171\",[153,3.942]],[\"name/172\",[160,57.991]],[\"parent/172\",[153,3.942]],[\"name/173\",[161,35.304]],[\"parent/173\",[]],[\"name/174\",[162,57.991]],[\"parent/174\",[161,3.424]],[\"name/175\",[163,57.991]],[\"parent/175\",[161,3.424]],[\"name/176\",[164,57.991]],[\"parent/176\",[161,3.424]],[\"name/177\",[165,57.991]],[\"parent/177\",[161,3.424]],[\"name/178\",[166,57.991]],[\"parent/178\",[161,3.424]],[\"name/179\",[167,57.991]],[\"parent/179\",[161,3.424]],[\"name/180\",[168,57.991]],[\"parent/180\",[161,3.424]],[\"name/181\",[169,52.883]],[\"parent/181\",[161,3.424]],[\"name/182\",[170,57.991]],[\"parent/182\",[161,3.424]],[\"name/183\",[171,57.991]],[\"parent/183\",[161,3.424]],[\"name/184\",[172,57.991]],[\"parent/184\",[161,3.424]],[\"name/185\",[173,57.991]],[\"parent/185\",[161,3.424]],[\"name/186\",[174,57.991]],[\"parent/186\",[161,3.424]],[\"name/187\",[175,40.645]],[\"parent/187\",[]],[\"name/188\",[176,57.991]],[\"parent/188\",[175,3.942]],[\"name/189\",[177,57.991]],[\"parent/189\",[175,3.942]],[\"name/190\",[178,57.991]],[\"parent/190\",[175,3.942]],[\"name/191\",[179,57.991]],[\"parent/191\",[175,3.942]],[\"name/192\",[180,52.883]],[\"parent/192\",[175,3.942]],[\"name/193\",[181,57.991]],[\"parent/193\",[175,3.942]],[\"name/194\",[182,57.991]],[\"parent/194\",[175,3.942]],[\"name/195\",[183,41.897]],[\"parent/195\",[]],[\"name/196\",[184,57.991]],[\"parent/196\",[183,4.063]],[\"name/197\",[185,57.991]],[\"parent/197\",[183,4.063]],[\"name/198\",[186,57.991]],[\"parent/198\",[183,4.063]],[\"name/199\",[187,57.991]],[\"parent/199\",[183,4.063]],[\"name/200\",[188,57.991]],[\"parent/200\",[183,4.063]],[\"name/201\",[189,57.991]],[\"parent/201\",[183,4.063]],[\"name/202\",[190,32.868]],[\"parent/202\",[]],[\"name/203\",[191,52.883]],[\"parent/203\",[190,3.187]],[\"name/204\",[192,57.991]],[\"parent/204\",[190,3.187]],[\"name/205\",[193,57.991]],[\"parent/205\",[190,3.187]],[\"name/206\",[194,57.991]],[\"parent/206\",[190,3.187]],[\"name/207\",[195,57.991]],[\"parent/207\",[190,3.187]],[\"name/208\",[196,57.991]],[\"parent/208\",[190,3.187]],[\"name/209\",[197,57.991]],[\"parent/209\",[190,3.187]],[\"name/210\",[198,57.991]],[\"parent/210\",[190,3.187]],[\"name/211\",[199,52.883]],[\"parent/211\",[190,3.187]],[\"name/212\",[200,57.991]],[\"parent/212\",[190,3.187]],[\"name/213\",[201,57.991]],[\"parent/213\",[190,3.187]],[\"name/214\",[202,57.991]],[\"parent/214\",[190,3.187]],[\"name/215\",[203,57.991]],[\"parent/215\",[190,3.187]],[\"name/216\",[204,57.991]],[\"parent/216\",[190,3.187]],[\"name/217\",[205,57.991]],[\"parent/217\",[190,3.187]],[\"name/218\",[206,57.991]],[\"parent/218\",[190,3.187]],[\"name/219\",[207,57.991]],[\"parent/219\",[190,3.187]],[\"name/220\",[208,26.072]],[\"parent/220\",[]],[\"name/221\",[209,57.991]],[\"parent/221\",[208,2.528]],[\"name/222\",[210,57.991]],[\"parent/222\",[211,5.128]],[\"name/223\",[212,57.991]],[\"parent/223\",[211,5.128]],[\"name/224\",[213,52.883]],[\"parent/224\",[208,2.528]],[\"name/225\",[214,38.532]],[\"parent/225\",[215,4.558]],[\"name/226\",[216,52.883]],[\"parent/226\",[215,4.558]],[\"name/227\",[217,52.883]],[\"parent/227\",[215,4.558]],[\"name/228\",[218,57.991]],[\"parent/228\",[215,4.558]],[\"name/229\",[219,52.883]],[\"parent/229\",[208,2.528]],[\"name/230\",[220,49.518]],[\"parent/230\",[221,4.558]],[\"name/231\",[214,38.532]],[\"parent/231\",[221,4.558]],[\"name/232\",[216,52.883]],[\"parent/232\",[221,4.558]],[\"name/233\",[217,52.883]],[\"parent/233\",[221,4.558]],[\"name/234\",[191,52.883]],[\"parent/234\",[208,2.528]],[\"name/235\",[220,49.518]],[\"parent/235\",[222,4.364]],[\"name/236\",[223,52.883]],[\"parent/236\",[222,4.364]],[\"name/237\",[224,52.883]],[\"parent/237\",[222,4.364]],[\"name/238\",[225,52.883]],[\"parent/238\",[222,4.364]],[\"name/239\",[226,52.883]],[\"parent/239\",[222,4.364]],[\"name/240\",[199,52.883]],[\"parent/240\",[208,2.528]],[\"name/241\",[227,41.897]],[\"parent/241\",[228,4.364]],[\"name/242\",[223,52.883]],[\"parent/242\",[228,4.364]],[\"name/243\",[224,52.883]],[\"parent/243\",[228,4.364]],[\"name/244\",[225,52.883]],[\"parent/244\",[228,4.364]],[\"name/245\",[226,52.883]],[\"parent/245\",[228,4.364]],[\"name/246\",[229,52.883]],[\"parent/246\",[208,2.528]],[\"name/247\",[220,49.518]],[\"parent/247\",[230,4.202]],[\"name/248\",[231,52.883]],[\"parent/248\",[230,4.202]],[\"name/249\",[232,52.883]],[\"parent/249\",[230,4.202]],[\"name/250\",[233,52.883]],[\"parent/250\",[230,4.202]],[\"name/251\",[234,52.883]],[\"parent/251\",[230,4.202]],[\"name/252\",[235,52.883]],[\"parent/252\",[230,4.202]],[\"name/253\",[236,52.883]],[\"parent/253\",[208,2.528]],[\"name/254\",[237,47.005]],[\"parent/254\",[238,4.202]],[\"name/255\",[231,52.883]],[\"parent/255\",[238,4.202]],[\"name/256\",[232,52.883]],[\"parent/256\",[238,4.202]],[\"name/257\",[233,52.883]],[\"parent/257\",[238,4.202]],[\"name/258\",[234,52.883]],[\"parent/258\",[238,4.202]],[\"name/259\",[235,52.883]],[\"parent/259\",[238,4.202]],[\"name/260\",[146,52.883]],[\"parent/260\",[208,2.528]],[\"name/261\",[227,41.897]],[\"parent/261\",[239,4.364]],[\"name/262\",[240,47.005]],[\"parent/262\",[239,4.364]],[\"name/263\",[241,52.883]],[\"parent/263\",[239,4.364]],[\"name/264\",[242,52.883]],[\"parent/264\",[239,4.364]],[\"name/265\",[243,57.991]],[\"parent/265\",[239,4.364]],[\"name/266\",[147,52.883]],[\"parent/266\",[208,2.528]],[\"name/267\",[244,57.991]],[\"parent/267\",[245,4.558]],[\"name/268\",[227,41.897]],[\"parent/268\",[245,4.558]],[\"name/269\",[241,52.883]],[\"parent/269\",[245,4.558]],[\"name/270\",[242,52.883]],[\"parent/270\",[245,4.558]],[\"name/271\",[137,52.883]],[\"parent/271\",[208,2.528]],[\"name/272\",[237,47.005]],[\"parent/272\",[246,4.364]],[\"name/273\",[247,49.518]],[\"parent/273\",[246,4.364]],[\"name/274\",[248,49.518]],[\"parent/274\",[246,4.364]],[\"name/275\",[227,41.897]],[\"parent/275\",[246,4.364]],[\"name/276\",[249,52.883]],[\"parent/276\",[246,4.364]],[\"name/277\",[138,52.883]],[\"parent/277\",[208,2.528]],[\"name/278\",[250,57.991]],[\"parent/278\",[251,4.364]],[\"name/279\",[227,41.897]],[\"parent/279\",[251,4.364]],[\"name/280\",[248,49.518]],[\"parent/280\",[251,4.364]],[\"name/281\",[249,52.883]],[\"parent/281\",[251,4.364]],[\"name/282\",[247,49.518]],[\"parent/282\",[251,4.364]],[\"name/283\",[169,52.883]],[\"parent/283\",[208,2.528]],[\"name/284\",[237,47.005]],[\"parent/284\",[252,3.493]],[\"name/285\",[253,57.991]],[\"parent/285\",[252,3.493]],[\"name/286\",[254,57.991]],[\"parent/286\",[252,3.493]],[\"name/287\",[255,57.991]],[\"parent/287\",[252,3.493]],[\"name/288\",[256,57.991]],[\"parent/288\",[252,3.493]],[\"name/289\",[257,47.005]],[\"parent/289\",[252,3.493]],[\"name/290\",[258,57.991]],[\"parent/290\",[252,3.493]],[\"name/291\",[259,57.991]],[\"parent/291\",[252,3.493]],[\"name/292\",[260,57.991]],[\"parent/292\",[252,3.493]],[\"name/293\",[261,57.991]],[\"parent/293\",[252,3.493]],[\"name/294\",[262,57.991]],[\"parent/294\",[252,3.493]],[\"name/295\",[263,57.991]],[\"parent/295\",[252,3.493]],[\"name/296\",[264,57.991]],[\"parent/296\",[252,3.493]],[\"name/297\",[265,52.883]],[\"parent/297\",[208,2.528]],[\"name/298\",[257,47.005]],[\"parent/298\",[266,5.128]],[\"name/299\",[267,57.991]],[\"parent/299\",[266,5.128]],[\"name/300\",[76,49.518]],[\"parent/300\",[208,2.528]],[\"name/301\",[214,38.532]],[\"parent/301\",[268,4.202]],[\"name/302\",[257,47.005]],[\"parent/302\",[268,4.202]],[\"name/303\",[269,49.518]],[\"parent/303\",[268,4.202]],[\"name/304\",[270,52.883]],[\"parent/304\",[268,4.202]],[\"name/305\",[271,52.883]],[\"parent/305\",[268,4.202]],[\"name/306\",[272,49.518]],[\"parent/306\",[268,4.202]],[\"name/307\",[273,52.883]],[\"parent/307\",[208,2.528]],[\"name/308\",[274,44.998]],[\"parent/308\",[275,4.063]],[\"name/309\",[214,38.532]],[\"parent/309\",[275,4.063]],[\"name/310\",[257,47.005]],[\"parent/310\",[275,4.063]],[\"name/311\",[269,49.518]],[\"parent/311\",[275,4.063]],[\"name/312\",[270,52.883]],[\"parent/312\",[275,4.063]],[\"name/313\",[271,52.883]],[\"parent/313\",[275,4.063]],[\"name/314\",[272,49.518]],[\"parent/314\",[275,4.063]],[\"name/315\",[89,49.518]],[\"parent/315\",[208,2.528]],[\"name/316\",[276,57.991]],[\"parent/316\",[277,3.737]],[\"name/317\",[214,38.532]],[\"parent/317\",[277,3.737]],[\"name/318\",[278,57.991]],[\"parent/318\",[277,3.737]],[\"name/319\",[269,49.518]],[\"parent/319\",[277,3.737]],[\"name/320\",[279,57.991]],[\"parent/320\",[277,3.737]],[\"name/321\",[280,57.991]],[\"parent/321\",[277,3.737]],[\"name/322\",[281,47.005]],[\"parent/322\",[277,3.737]],[\"name/323\",[272,49.518]],[\"parent/323\",[277,3.737]],[\"name/324\",[282,57.991]],[\"parent/324\",[277,3.737]],[\"name/325\",[283,57.991]],[\"parent/325\",[277,3.737]],[\"name/326\",[284,57.991]],[\"parent/326\",[208,2.528]],[\"name/327\",[281,47.005]],[\"parent/327\",[285,4.364]],[\"name/328\",[286,57.991]],[\"parent/328\",[285,4.364]],[\"name/329\",[65,47.005]],[\"parent/329\",[285,4.364]],[\"name/330\",[214,38.532]],[\"parent/330\",[287,5.128]],[\"name/331\",[288,57.991]],[\"parent/331\",[285,4.364]],[\"name/332\",[65,47.005]],[\"parent/332\",[285,4.364]],[\"name/333\",[289,57.991]],[\"parent/333\",[287,5.128]],[\"name/334\",[290,57.991]],[\"parent/334\",[208,2.528]],[\"name/335\",[291,57.991]],[\"parent/335\",[292,5.128]],[\"name/336\",[65,47.005]],[\"parent/336\",[292,5.128]],[\"name/337\",[293,57.991]],[\"parent/337\",[294,5.128]],[\"name/338\",[295,57.991]],[\"parent/338\",[294,5.128]],[\"name/339\",[296,52.883]],[\"parent/339\",[208,2.528]],[\"name/340\",[274,44.998]],[\"parent/340\",[297,4.802]],[\"name/341\",[298,47.005]],[\"parent/341\",[297,4.802]],[\"name/342\",[281,47.005]],[\"parent/342\",[297,4.802]],[\"name/343\",[299,52.883]],[\"parent/343\",[208,2.528]],[\"name/344\",[247,49.518]],[\"parent/344\",[300,4.558]],[\"name/345\",[274,44.998]],[\"parent/345\",[300,4.558]],[\"name/346\",[298,47.005]],[\"parent/346\",[300,4.558]],[\"name/347\",[281,47.005]],[\"parent/347\",[300,4.558]],[\"name/348\",[301,52.883]],[\"parent/348\",[208,2.528]],[\"name/349\",[298,47.005]],[\"parent/349\",[302,5.128]],[\"name/350\",[214,38.532]],[\"parent/350\",[302,5.128]],[\"name/351\",[180,52.883]],[\"parent/351\",[208,2.528]],[\"name/352\",[303,49.518]],[\"parent/352\",[304,5.128]],[\"name/353\",[214,38.532]],[\"parent/353\",[304,5.128]],[\"name/354\",[154,52.883]],[\"parent/354\",[208,2.528]],[\"name/355\",[240,47.005]],[\"parent/355\",[305,4.202]],[\"name/356\",[306,52.883]],[\"parent/356\",[305,4.202]],[\"name/357\",[303,49.518]],[\"parent/357\",[305,4.202]],[\"name/358\",[307,52.883]],[\"parent/358\",[305,4.202]],[\"name/359\",[308,52.883]],[\"parent/359\",[305,4.202]],[\"name/360\",[309,57.991]],[\"parent/360\",[305,4.202]],[\"name/361\",[158,52.883]],[\"parent/361\",[208,2.528]],[\"name/362\",[310,57.991]],[\"parent/362\",[311,4.063]],[\"name/363\",[240,47.005]],[\"parent/363\",[311,4.063]],[\"name/364\",[306,52.883]],[\"parent/364\",[311,4.063]],[\"name/365\",[303,49.518]],[\"parent/365\",[311,4.063]],[\"name/366\",[307,52.883]],[\"parent/366\",[311,4.063]],[\"name/367\",[308,52.883]],[\"parent/367\",[311,4.063]],[\"name/368\",[312,57.991]],[\"parent/368\",[311,4.063]],[\"name/369\",[152,52.883]],[\"parent/369\",[208,2.528]],[\"name/370\",[227,41.897]],[\"parent/370\",[313,4.364]],[\"name/371\",[237,47.005]],[\"parent/371\",[313,4.364]],[\"name/372\",[274,44.998]],[\"parent/372\",[313,4.364]],[\"name/373\",[314,57.991]],[\"parent/373\",[313,4.364]],[\"name/374\",[248,49.518]],[\"parent/374\",[313,4.364]],[\"name/375\",[315,57.991]],[\"parent/375\",[208,2.528]],[\"name/376\",[274,44.998]],[\"parent/376\",[316,5.128]],[\"name/377\",[227,41.897]],[\"parent/377\",[316,5.128]],[\"name/378\",[128,52.883]],[\"parent/378\",[208,2.528]],[\"name/379\",[240,47.005]],[\"parent/379\",[317,5.128]],[\"name/380\",[298,47.005]],[\"parent/380\",[317,5.128]],[\"name/381\",[109,49.518]],[\"parent/381\",[208,2.528]],[\"name/382\",[318,52.883]],[\"parent/382\",[319,4.364]],[\"name/383\",[214,38.532]],[\"parent/383\",[319,4.364]],[\"name/384\",[320,52.883]],[\"parent/384\",[319,4.364]],[\"name/385\",[321,52.883]],[\"parent/385\",[319,4.364]],[\"name/386\",[322,52.883]],[\"parent/386\",[319,4.364]],[\"name/387\",[110,49.518]],[\"parent/387\",[208,2.528]],[\"name/388\",[323,57.991]],[\"parent/388\",[324,4.202]],[\"name/389\",[318,52.883]],[\"parent/389\",[324,4.202]],[\"name/390\",[214,38.532]],[\"parent/390\",[324,4.202]],[\"name/391\",[320,52.883]],[\"parent/391\",[324,4.202]],[\"name/392\",[321,52.883]],[\"parent/392\",[324,4.202]],[\"name/393\",[322,52.883]],[\"parent/393\",[324,4.202]],[\"name/394\",[325,57.991]],[\"parent/394\",[208,2.528]],[\"name/395\",[326,57.991]],[\"parent/395\",[208,2.528]],[\"name/396\",[327,57.991]],[\"parent/396\",[208,2.528]],[\"name/397\",[328,57.991]],[\"parent/397\",[208,2.528]],[\"name/398\",[329,57.991]],[\"parent/398\",[208,2.528]],[\"name/399\",[330,57.991]],[\"parent/399\",[208,2.528]],[\"name/400\",[331,35.304]],[\"parent/400\",[]],[\"name/401\",[332,57.991]],[\"parent/401\",[331,3.424]],[\"name/402\",[333,57.991]],[\"parent/402\",[331,3.424]],[\"name/403\",[334,57.991]],[\"parent/403\",[331,3.424]],[\"name/404\",[335,57.991]],[\"parent/404\",[331,3.424]],[\"name/405\",[336,57.991]],[\"parent/405\",[331,3.424]],[\"name/406\",[337,57.991]],[\"parent/406\",[331,3.424]],[\"name/407\",[265,52.883]],[\"parent/407\",[331,3.424]],[\"name/408\",[338,57.991]],[\"parent/408\",[331,3.424]],[\"name/409\",[339,57.991]],[\"parent/409\",[331,3.424]],[\"name/410\",[340,57.991]],[\"parent/410\",[331,3.424]],[\"name/411\",[341,57.991]],[\"parent/411\",[331,3.424]],[\"name/412\",[342,57.991]],[\"parent/412\",[331,3.424]],[\"name/413\",[343,57.991]],[\"parent/413\",[331,3.424]],[\"name/414\",[344,44.998]],[\"parent/414\",[]],[\"name/415\",[345,57.991]],[\"parent/415\",[344,4.364]],[\"name/416\",[346,57.991]],[\"parent/416\",[344,4.364]],[\"name/417\",[347,57.991]],[\"parent/417\",[344,4.364]],[\"name/418\",[348,57.991]],[\"parent/418\",[344,4.364]],[\"name/419\",[349,38.532]],[\"parent/419\",[]],[\"name/420\",[213,52.883]],[\"parent/420\",[349,3.737]],[\"name/421\",[350,57.991]],[\"parent/421\",[349,3.737]],[\"name/422\",[351,57.991]],[\"parent/422\",[349,3.737]],[\"name/423\",[352,57.991]],[\"parent/423\",[349,3.737]],[\"name/424\",[353,57.991]],[\"parent/424\",[349,3.737]],[\"name/425\",[354,57.991]],[\"parent/425\",[349,3.737]],[\"name/426\",[219,52.883]],[\"parent/426\",[349,3.737]],[\"name/427\",[355,57.991]],[\"parent/427\",[349,3.737]],[\"name/428\",[356,57.991]],[\"parent/428\",[349,3.737]],[\"name/429\",[357,39.533]],[\"parent/429\",[]],[\"name/430\",[296,52.883]],[\"parent/430\",[357,3.834]],[\"name/431\",[358,57.991]],[\"parent/431\",[357,3.834]],[\"name/432\",[359,57.991]],[\"parent/432\",[357,3.834]],[\"name/433\",[360,57.991]],[\"parent/433\",[357,3.834]],[\"name/434\",[299,52.883]],[\"parent/434\",[357,3.834]],[\"name/435\",[361,57.991]],[\"parent/435\",[357,3.834]],[\"name/436\",[362,57.991]],[\"parent/436\",[357,3.834]],[\"name/437\",[363,57.991]],[\"parent/437\",[357,3.834]],[\"name/438\",[364,47.005]],[\"parent/438\",[]],[\"name/439\",[365,57.991]],[\"parent/439\",[364,4.558]],[\"name/440\",[366,57.991]],[\"parent/440\",[364,4.558]],[\"name/441\",[367,57.991]],[\"parent/441\",[364,4.558]],[\"name/442\",[368,31.841]],[\"parent/442\",[]],[\"name/443\",[76,49.518]],[\"parent/443\",[368,3.088]],[\"name/444\",[369,57.991]],[\"parent/444\",[368,3.088]],[\"name/445\",[370,57.991]],[\"parent/445\",[368,3.088]],[\"name/446\",[371,57.991]],[\"parent/446\",[368,3.088]],[\"name/447\",[372,57.991]],[\"parent/447\",[368,3.088]],[\"name/448\",[373,57.991]],[\"parent/448\",[368,3.088]],[\"name/449\",[374,57.991]],[\"parent/449\",[368,3.088]],[\"name/450\",[375,57.991]],[\"parent/450\",[368,3.088]],[\"name/451\",[376,57.991]],[\"parent/451\",[368,3.088]],[\"name/452\",[377,57.991]],[\"parent/452\",[368,3.088]],[\"name/453\",[378,57.991]],[\"parent/453\",[368,3.088]],[\"name/454\",[379,57.991]],[\"parent/454\",[368,3.088]],[\"name/455\",[273,52.883]],[\"parent/455\",[368,3.088]],[\"name/456\",[80,52.883]],[\"parent/456\",[368,3.088]],[\"name/457\",[380,57.991]],[\"parent/457\",[368,3.088]],[\"name/458\",[381,57.991]],[\"parent/458\",[368,3.088]],[\"name/459\",[89,49.518]],[\"parent/459\",[368,3.088]],[\"name/460\",[382,57.991]],[\"parent/460\",[368,3.088]],[\"name/461\",[383,57.991]],[\"parent/461\",[368,3.088]],[\"name/462\",[384,39.533]],[\"parent/462\",[]],[\"name/463\",[385,57.991]],[\"parent/463\",[384,3.834]],[\"name/464\",[386,57.991]],[\"parent/464\",[384,3.834]],[\"name/465\",[387,57.991]],[\"parent/465\",[384,3.834]],[\"name/466\",[388,57.991]],[\"parent/466\",[384,3.834]],[\"name/467\",[389,57.991]],[\"parent/467\",[384,3.834]],[\"name/468\",[301,52.883]],[\"parent/468\",[384,3.834]],[\"name/469\",[390,57.991]],[\"parent/469\",[384,3.834]],[\"name/470\",[391,57.991]],[\"parent/470\",[384,3.834]],[\"name/471\",[392,43.328]],[\"parent/471\",[]],[\"name/472\",[393,57.991]],[\"parent/472\",[392,4.202]],[\"name/473\",[394,57.991]],[\"parent/473\",[392,4.202]],[\"name/474\",[395,57.991]],[\"parent/474\",[392,4.202]],[\"name/475\",[396,57.991]],[\"parent/475\",[392,4.202]],[\"name/476\",[397,57.991]],[\"parent/476\",[392,4.202]],[\"name/477\",[398,38.532]],[\"parent/477\",[]],[\"name/478\",[229,52.883]],[\"parent/478\",[398,3.737]],[\"name/479\",[399,57.991]],[\"parent/479\",[398,3.737]],[\"name/480\",[100,52.883]],[\"parent/480\",[398,3.737]],[\"name/481\",[236,52.883]],[\"parent/481\",[398,3.737]],[\"name/482\",[101,52.883]],[\"parent/482\",[398,3.737]],[\"name/483\",[400,57.991]],[\"parent/483\",[398,3.737]],[\"name/484\",[401,57.991]],[\"parent/484\",[398,3.737]],[\"name/485\",[105,52.883]],[\"parent/485\",[398,3.737]],[\"name/486\",[402,57.991]],[\"parent/486\",[398,3.737]],[\"name/487\",[403,41.897]],[\"parent/487\",[]],[\"name/488\",[107,52.883]],[\"parent/488\",[403,4.063]],[\"name/489\",[404,57.991]],[\"parent/489\",[403,4.063]],[\"name/490\",[405,57.991]],[\"parent/490\",[403,4.063]],[\"name/491\",[109,49.518]],[\"parent/491\",[403,4.063]],[\"name/492\",[110,49.518]],[\"parent/492\",[403,4.063]],[\"name/493\",[111,52.883]],[\"parent/493\",[403,4.063]]],\"invertedIndex\":[[\"__type\",{\"_index\":65,\"name\":{\"69\":{},\"329\":{},\"332\":{},\"336\":{}},\"parent\":{}}],[\"_count\",{\"_index\":288,\"name\":{\"331\":{}},\"parent\":{}}],[\"accountstatus\",{\"_index\":226,\"name\":{\"239\":{},\"245\":{}},\"parent\":{}}],[\"addattachmentstodatabase\",{\"_index\":51,\"name\":{\"53\":{}},\"parent\":{}}],[\"addjobapplicationtodatabase\",{\"_index\":49,\"name\":{\"51\":{}},\"parent\":{}}],[\"addosoctouser\",{\"_index\":185,\"name\":{\"197\":{}},\"parent\":{}}],[\"addpersontodatabase\",{\"_index\":47,\"name\":{\"49\":{}},\"parent\":{}}],[\"addrolestodatabase\",{\"_index\":52,\"name\":{\"54\":{}},\"parent\":{}}],[\"addsessionkey\",{\"_index\":393,\"name\":{\"472\":{}},\"parent\":{}}],[\"addskillstodatabase\",{\"_index\":50,\"name\":{\"52\":{}},\"parent\":{}}],[\"addstudenttodatabase\",{\"_index\":48,\"name\":{\"50\":{}},\"parent\":{}}],[\"addstudenttoproject\",{\"_index\":152,\"name\":{\"164\":{},\"369\":{}},\"parent\":{}}],[\"alumni\",{\"_index\":235,\"name\":{\"252\":{},\"259\":{}},\"parent\":{}}],[\"assigncoach\",{\"_index\":86,\"name\":{\"91\":{}},\"parent\":{}}],[\"assignstudent\",{\"_index\":88,\"name\":{\"93\":{}},\"parent\":{}}],[\"cc\",{\"_index\":322,\"name\":{\"386\":{},\"393\":{}},\"parent\":{}}],[\"changeemailstatusofjobapplication\",{\"_index\":167,\"name\":{\"179\":{}},\"parent\":{}}],[\"checkcode\",{\"_index\":93,\"name\":{\"99\":{}},\"parent\":{}}],[\"checkiffinalevaluationexists\",{\"_index\":145,\"name\":{\"157\":{}},\"parent\":{}}],[\"checkquestionsexist\",{\"_index\":16,\"name\":{\"18\":{}},\"parent\":{}}],[\"checksessionkey\",{\"_index\":394,\"name\":{\"473\":{}},\"parent\":{}}],[\"checkstate\",{\"_index\":58,\"name\":{\"61\":{}},\"parent\":{}}],[\"checkwordinanswer\",{\"_index\":15,\"name\":{\"17\":{}},\"parent\":{}}],[\"content\",{\"_index\":320,\"name\":{\"384\":{},\"391\":{}},\"parent\":{}}],[\"contract\",{\"_index\":289,\"name\":{\"333\":{}},\"parent\":{}}],[\"contractid\",{\"_index\":250,\"name\":{\"278\":{}},\"parent\":{}}],[\"contractsbyproject\",{\"_index\":142,\"name\":{\"154\":{}},\"parent\":{}}],[\"contractsforstudent\",{\"_index\":141,\"name\":{\"153\":{}},\"parent\":{}}],[\"contractstatus\",{\"_index\":249,\"name\":{\"276\":{},\"281\":{}},\"parent\":{}}],[\"createappliedrole\",{\"_index\":128,\"name\":{\"140\":{},\"378\":{}},\"parent\":{}}],[\"createattachment\",{\"_index\":132,\"name\":{\"144\":{}},\"parent\":{}}],[\"createcontract\",{\"_index\":137,\"name\":{\"149\":{},\"271\":{}},\"parent\":{}}],[\"createdat\",{\"_index\":264,\"name\":{\"296\":{}},\"parent\":{}}],[\"createemail\",{\"_index\":95,\"name\":{\"102\":{}},\"parent\":{}}],[\"createevaluationforstudent\",{\"_index\":146,\"name\":{\"158\":{},\"260\":{}},\"parent\":{}}],[\"createform\",{\"_index\":53,\"name\":{\"55\":{}},\"parent\":{}}],[\"createjobapplication\",{\"_index\":169,\"name\":{\"181\":{},\"283\":{}},\"parent\":{}}],[\"createjobapplicationskill\",{\"_index\":154,\"name\":{\"166\":{},\"354\":{}},\"parent\":{}}],[\"createlanguage\",{\"_index\":176,\"name\":{\"188\":{}},\"parent\":{}}],[\"createloginuser\",{\"_index\":191,\"name\":{\"203\":{},\"234\":{}},\"parent\":{}}],[\"createorupdatereset\",{\"_index\":345,\"name\":{\"415\":{}},\"parent\":{}}],[\"createosoc\",{\"_index\":332,\"name\":{\"401\":{}},\"parent\":{}}],[\"createosocedition\",{\"_index\":71,\"name\":{\"75\":{}},\"parent\":{}}],[\"createperson\",{\"_index\":213,\"name\":{\"224\":{},\"420\":{}},\"parent\":{}}],[\"createproject\",{\"_index\":76,\"name\":{\"81\":{},\"300\":{},\"443\":{}},\"parent\":{}}],[\"createprojectrole\",{\"_index\":296,\"name\":{\"339\":{},\"430\":{}},\"parent\":{}}],[\"createprojectrolefor\",{\"_index\":83,\"name\":{\"88\":{}},\"parent\":{}}],[\"createprojectuser\",{\"_index\":365,\"name\":{\"439\":{}},\"parent\":{}}],[\"createrole\",{\"_index\":385,\"name\":{\"463\":{}},\"parent\":{}}],[\"createstudent\",{\"_index\":229,\"name\":{\"246\":{},\"478\":{}},\"parent\":{}}],[\"createstudentconfirmation\",{\"_index\":104,\"name\":{\"112\":{}},\"parent\":{}}],[\"createstudentrole\",{\"_index\":98,\"name\":{\"105\":{}},\"parent\":{}}],[\"createstudentsuggestion\",{\"_index\":102,\"name\":{\"110\":{}},\"parent\":{}}],[\"createtemplate\",{\"_index\":109,\"name\":{\"118\":{},\"381\":{},\"491\":{}},\"parent\":{}}],[\"createuseracceptance\",{\"_index\":117,\"name\":{\"127\":{}},\"parent\":{}}],[\"createuserpermission\",{\"_index\":122,\"name\":{\"132\":{}},\"parent\":{}}],[\"createuserrequest\",{\"_index\":115,\"name\":{\"125\":{}},\"parent\":{}}],[\"currentpage\",{\"_index\":210,\"name\":{\"222\":{}},\"parent\":{}}],[\"dbpagination\",{\"_index\":209,\"name\":{\"221\":{}},\"parent\":{}}],[\"decision\",{\"_index\":241,\"name\":{\"263\":{},\"269\":{}},\"parent\":{}}],[\"deleteadmin\",{\"_index\":3,\"name\":{\"3\":{}},\"parent\":{}}],[\"deleteallattachmentsforapplication\",{\"_index\":134,\"name\":{\"146\":{}},\"parent\":{}}],[\"deleteappliedrolesbyjobapplication\",{\"_index\":130,\"name\":{\"142\":{}},\"parent\":{}}],[\"deleteattachment\",{\"_index\":133,\"name\":{\"145\":{}},\"parent\":{}}],[\"deletecoach\",{\"_index\":8,\"name\":{\"8\":{}},\"parent\":{}}],[\"deleteevaluationsbyjobapplication\",{\"_index\":150,\"name\":{\"162\":{}},\"parent\":{}}],[\"deletejobapplication\",{\"_index\":168,\"name\":{\"180\":{}},\"parent\":{}}],[\"deletejobapplicationsfromstudent\",{\"_index\":166,\"name\":{\"178\":{}},\"parent\":{}}],[\"deletejobapplicationskill\",{\"_index\":159,\"name\":{\"171\":{}},\"parent\":{}}],[\"deletelanguage\",{\"_index\":181,\"name\":{\"193\":{}},\"parent\":{}}],[\"deletelanguagebyname\",{\"_index\":182,\"name\":{\"194\":{}},\"parent\":{}}],[\"deleteloginuserbyid\",{\"_index\":200,\"name\":{\"212\":{}},\"parent\":{}}],[\"deleteloginuserbypersonid\",{\"_index\":201,\"name\":{\"213\":{}},\"parent\":{}}],[\"deleteloginuserfromdb\",{\"_index\":202,\"name\":{\"214\":{}},\"parent\":{}}],[\"deleteosoc\",{\"_index\":338,\"name\":{\"408\":{}},\"parent\":{}}],[\"deleteosocbyyear\",{\"_index\":339,\"name\":{\"409\":{}},\"parent\":{}}],[\"deleteosoceditionrequest\",{\"_index\":74,\"name\":{\"78\":{}},\"parent\":{}}],[\"deleteosocfromdb\",{\"_index\":340,\"name\":{\"410\":{}},\"parent\":{}}],[\"deleteosocsforloginuser\",{\"_index\":186,\"name\":{\"198\":{}},\"parent\":{}}],[\"deleteosocsloginconnectionfromosoc\",{\"_index\":187,\"name\":{\"199\":{}},\"parent\":{}}],[\"deletepersonbyid\",{\"_index\":355,\"name\":{\"427\":{}},\"parent\":{}}],[\"deletepersonfromdb\",{\"_index\":356,\"name\":{\"428\":{}},\"parent\":{}}],[\"deleteproject\",{\"_index\":80,\"name\":{\"85\":{},\"456\":{}},\"parent\":{}}],[\"deleteprojectbyosocedition\",{\"_index\":380,\"name\":{\"457\":{}},\"parent\":{}}],[\"deleteprojectbypartner\",{\"_index\":381,\"name\":{\"458\":{}},\"parent\":{}}],[\"deleteprojectfromdb\",{\"_index\":383,\"name\":{\"461\":{}},\"parent\":{}}],[\"deleteprojectrole\",{\"_index\":361,\"name\":{\"435\":{}},\"parent\":{}}],[\"deleteprojectuser\",{\"_index\":367,\"name\":{\"441\":{}},\"parent\":{}}],[\"deleteresetwithloginuser\",{\"_index\":347,\"name\":{\"417\":{}},\"parent\":{}}],[\"deleteresetwithresetid\",{\"_index\":348,\"name\":{\"418\":{}},\"parent\":{}}],[\"deleterole\",{\"_index\":390,\"name\":{\"469\":{}},\"parent\":{}}],[\"deleterolebyname\",{\"_index\":391,\"name\":{\"470\":{}},\"parent\":{}}],[\"deleteskillsbyjobapplicationid\",{\"_index\":160,\"name\":{\"172\":{}},\"parent\":{}}],[\"deletestudent\",{\"_index\":101,\"name\":{\"109\":{},\"482\":{}},\"parent\":{}}],[\"deletestudentfromdb\",{\"_index\":400,\"name\":{\"483\":{}},\"parent\":{}}],[\"deletetemplate\",{\"_index\":111,\"name\":{\"120\":{},\"493\":{}},\"parent\":{}}],[\"deleteuserpermission\",{\"_index\":123,\"name\":{\"133\":{}},\"parent\":{}}],[\"deleteuserrequest\",{\"_index\":118,\"name\":{\"128\":{}},\"parent\":{}}],[\"description\",{\"_index\":272,\"name\":{\"306\":{},\"314\":{},\"323\":{}},\"parent\":{}}],[\"eduduration\",{\"_index\":260,\"name\":{\"292\":{}},\"parent\":{}}],[\"eduinstitute\",{\"_index\":262,\"name\":{\"294\":{}},\"parent\":{}}],[\"edulevel\",{\"_index\":259,\"name\":{\"291\":{}},\"parent\":{}}],[\"edus\",{\"_index\":258,\"name\":{\"290\":{}},\"parent\":{}}],[\"eduyear\",{\"_index\":261,\"name\":{\"293\":{}},\"parent\":{}}],[\"email\",{\"_index\":217,\"name\":{\"227\":{},\"233\":{}},\"parent\":{}}],[\"emailstatus\",{\"_index\":263,\"name\":{\"295\":{}},\"parent\":{}}],[\"end_date\",{\"_index\":280,\"name\":{\"321\":{}},\"parent\":{}}],[\"enddate\",{\"_index\":271,\"name\":{\"305\":{},\"313\":{}},\"parent\":{}}],[\"evaluation_id\",{\"_index\":244,\"name\":{\"267\":{}},\"parent\":{}}],[\"filterboolean\",{\"_index\":330,\"name\":{\"399\":{}},\"parent\":{}}],[\"filterchosenoption\",{\"_index\":14,\"name\":{\"16\":{}},\"parent\":{}}],[\"filterloginusers\",{\"_index\":204,\"name\":{\"216\":{}},\"parent\":{}}],[\"filternumber\",{\"_index\":327,\"name\":{\"396\":{}},\"parent\":{}}],[\"filternumberarray\",{\"_index\":328,\"name\":{\"397\":{}},\"parent\":{}}],[\"filterosocs\",{\"_index\":342,\"name\":{\"412\":{}},\"parent\":{}}],[\"filterprojects\",{\"_index\":89,\"name\":{\"94\":{},\"315\":{},\"459\":{}},\"parent\":{}}],[\"filterprojectsloginuser\",{\"_index\":290,\"name\":{\"334\":{}},\"parent\":{}}],[\"filterprojectsrole\",{\"_index\":284,\"name\":{\"326\":{}},\"parent\":{}}],[\"filterquestion\",{\"_index\":13,\"name\":{\"15\":{}},\"parent\":{}}],[\"filtersort\",{\"_index\":325,\"name\":{\"394\":{}},\"parent\":{}}],[\"filterstring\",{\"_index\":326,\"name\":{\"395\":{}},\"parent\":{}}],[\"filterstringarray\",{\"_index\":329,\"name\":{\"398\":{}},\"parent\":{}}],[\"filterstudents\",{\"_index\":105,\"name\":{\"113\":{},\"485\":{}},\"parent\":{}}],[\"filterusers\",{\"_index\":119,\"name\":{\"129\":{}},\"parent\":{}}],[\"filteryear\",{\"_index\":73,\"name\":{\"77\":{}},\"parent\":{}}],[\"findresetbycode\",{\"_index\":346,\"name\":{\"416\":{}},\"parent\":{}}],[\"funfact\",{\"_index\":254,\"name\":{\"286\":{}},\"parent\":{}}],[\"gender\",{\"_index\":231,\"name\":{\"248\":{},\"255\":{}},\"parent\":{}}],[\"genstate\",{\"_index\":57,\"name\":{\"60\":{}},\"parent\":{}}],[\"getalljobapplicationskill\",{\"_index\":155,\"name\":{\"167\":{}},\"parent\":{}}],[\"getalljobapplicationskillbyjobapplication\",{\"_index\":156,\"name\":{\"168\":{}},\"parent\":{}}],[\"getalllanguages\",{\"_index\":177,\"name\":{\"189\":{}},\"parent\":{}}],[\"getallloginusers\",{\"_index\":192,\"name\":{\"204\":{}},\"parent\":{}}],[\"getallosoc\",{\"_index\":333,\"name\":{\"402\":{}},\"parent\":{}}],[\"getallpersons\",{\"_index\":350,\"name\":{\"421\":{}},\"parent\":{}}],[\"getallprojects\",{\"_index\":369,\"name\":{\"444\":{}},\"parent\":{}}],[\"getallroles\",{\"_index\":386,\"name\":{\"464\":{}},\"parent\":{}}],[\"getallstudents\",{\"_index\":399,\"name\":{\"479\":{}},\"parent\":{}}],[\"getalltemplates\",{\"_index\":107,\"name\":{\"116\":{},\"488\":{}},\"parent\":{}}],[\"getalumni\",{\"_index\":25,\"name\":{\"27\":{}},\"parent\":{}}],[\"getappliedroles\",{\"_index\":45,\"name\":{\"47\":{}},\"parent\":{}}],[\"getappliedrolesbyjobapplication\",{\"_index\":129,\"name\":{\"141\":{}},\"parent\":{}}],[\"getappliedyearsforstudent\",{\"_index\":402,\"name\":{\"486\":{}},\"parent\":{}}],[\"getattachmentbyid\",{\"_index\":135,\"name\":{\"147\":{}},\"parent\":{}}],[\"getbestskill\",{\"_index\":39,\"name\":{\"41\":{}},\"parent\":{}}],[\"getbirthname\",{\"_index\":17,\"name\":{\"19\":{}},\"parent\":{}}],[\"getcurrentuser\",{\"_index\":121,\"name\":{\"131\":{}},\"parent\":{}}],[\"getcv\",{\"_index\":41,\"name\":{\"43\":{}},\"parent\":{}}],[\"getdraftedstudents\",{\"_index\":81,\"name\":{\"86\":{}},\"parent\":{}}],[\"geteducationduration\",{\"_index\":33,\"name\":{\"35\":{}},\"parent\":{}}],[\"geteducationlevel\",{\"_index\":32,\"name\":{\"34\":{}},\"parent\":{}}],[\"geteducations\",{\"_index\":31,\"name\":{\"33\":{}},\"parent\":{}}],[\"geteducationuniversity\",{\"_index\":35,\"name\":{\"37\":{}},\"parent\":{}}],[\"geteducationyear\",{\"_index\":34,\"name\":{\"36\":{}},\"parent\":{}}],[\"getemail\",{\"_index\":19,\"name\":{\"21\":{}},\"parent\":{}}],[\"getenglishlevel\",{\"_index\":38,\"name\":{\"40\":{}},\"parent\":{}}],[\"getevaluationbypartiesfor\",{\"_index\":149,\"name\":{\"161\":{}},\"parent\":{}}],[\"getevaluationsbyyearforstudent\",{\"_index\":174,\"name\":{\"186\":{}},\"parent\":{}}],[\"getfollowup\",{\"_index\":10,\"name\":{\"11\":{}},\"parent\":{}}],[\"getfreespotsfor\",{\"_index\":82,\"name\":{\"87\":{}},\"parent\":{}}],[\"getfunfact\",{\"_index\":28,\"name\":{\"30\":{}},\"parent\":{}}],[\"getgender\",{\"_index\":22,\"name\":{\"24\":{}},\"parent\":{}}],[\"gethome\",{\"_index\":56,\"name\":{\"59\":{}},\"parent\":{}}],[\"getjobapplication\",{\"_index\":171,\"name\":{\"183\":{}},\"parent\":{}}],[\"getjobapplicationbyyear\",{\"_index\":172,\"name\":{\"184\":{}},\"parent\":{}}],[\"getjobapplicationbyyearforstudent\",{\"_index\":173,\"name\":{\"185\":{}},\"parent\":{}}],[\"getjobapplicationskill\",{\"_index\":157,\"name\":{\"169\":{}},\"parent\":{}}],[\"getlanguage\",{\"_index\":178,\"name\":{\"190\":{}},\"parent\":{}}],[\"getlanguagebyname\",{\"_index\":179,\"name\":{\"191\":{}},\"parent\":{}}],[\"getlastname\",{\"_index\":18,\"name\":{\"20\":{}},\"parent\":{}}],[\"getlatestapplicationrolesforstudent\",{\"_index\":165,\"name\":{\"177\":{}},\"parent\":{}}],[\"getlatestjobapplicationofstudent\",{\"_index\":170,\"name\":{\"182\":{}},\"parent\":{}}],[\"getlatestosoc\",{\"_index\":334,\"name\":{\"403\":{}},\"parent\":{}}],[\"getloginuserbyevaluationid\",{\"_index\":148,\"name\":{\"160\":{}},\"parent\":{}}],[\"getloginuserbyid\",{\"_index\":203,\"name\":{\"215\":{}},\"parent\":{}}],[\"getloginuserosocbyids\",{\"_index\":184,\"name\":{\"196\":{}},\"parent\":{}}],[\"getmostfluentlanguage\",{\"_index\":37,\"name\":{\"39\":{}},\"parent\":{}}],[\"getmotivation\",{\"_index\":43,\"name\":{\"45\":{}},\"parent\":{}}],[\"getnewestosoc\",{\"_index\":341,\"name\":{\"411\":{}},\"parent\":{}}],[\"getnickname\",{\"_index\":24,\"name\":{\"26\":{}},\"parent\":{}}],[\"getnumberoffreepositions\",{\"_index\":362,\"name\":{\"436\":{}},\"parent\":{}}],[\"getnumberofrolesbyprojectandrole\",{\"_index\":359,\"name\":{\"432\":{}},\"parent\":{}}],[\"getosocafteryear\",{\"_index\":337,\"name\":{\"406\":{}},\"parent\":{}}],[\"getosocbeforeyear\",{\"_index\":336,\"name\":{\"405\":{}},\"parent\":{}}],[\"getosocbyid\",{\"_index\":343,\"name\":{\"413\":{}},\"parent\":{}}],[\"getosocbyyear\",{\"_index\":335,\"name\":{\"404\":{}},\"parent\":{}}],[\"getosocyearsforloginuser\",{\"_index\":207,\"name\":{\"219\":{}},\"parent\":{}}],[\"getosocyearsforloginuserbyid\",{\"_index\":189,\"name\":{\"201\":{}},\"parent\":{}}],[\"getpasswordloginuser\",{\"_index\":194,\"name\":{\"206\":{}},\"parent\":{}}],[\"getpasswordloginuserbyperson\",{\"_index\":193,\"name\":{\"205\":{}},\"parent\":{}}],[\"getpasswordpersonbyemail\",{\"_index\":351,\"name\":{\"422\":{}},\"parent\":{}}],[\"getpasswordpersonbygithub\",{\"_index\":352,\"name\":{\"423\":{}},\"parent\":{}}],[\"getphonenumber\",{\"_index\":23,\"name\":{\"25\":{}},\"parent\":{}}],[\"getportfolio\",{\"_index\":42,\"name\":{\"44\":{}},\"parent\":{}}],[\"getproject\",{\"_index\":78,\"name\":{\"83\":{}},\"parent\":{}}],[\"getprojectbyid\",{\"_index\":370,\"name\":{\"445\":{}},\"parent\":{}}],[\"getprojectbyname\",{\"_index\":371,\"name\":{\"446\":{}},\"parent\":{}}],[\"getprojectrolebyid\",{\"_index\":363,\"name\":{\"437\":{}},\"parent\":{}}],[\"getprojectrolenamesbyproject\",{\"_index\":360,\"name\":{\"433\":{}},\"parent\":{}}],[\"getprojectrolesbyproject\",{\"_index\":358,\"name\":{\"431\":{}},\"parent\":{}}],[\"getprojectrolewithrolename\",{\"_index\":389,\"name\":{\"467\":{}},\"parent\":{}}],[\"getprojectsbyenddate\",{\"_index\":377,\"name\":{\"452\":{}},\"parent\":{}}],[\"getprojectsbyosocedition\",{\"_index\":372,\"name\":{\"447\":{}},\"parent\":{}}],[\"getprojectsbypartner\",{\"_index\":373,\"name\":{\"448\":{}},\"parent\":{}}],[\"getprojectsbystartdate\",{\"_index\":374,\"name\":{\"449\":{}},\"parent\":{}}],[\"getprojectsendedafterdate\",{\"_index\":378,\"name\":{\"453\":{}},\"parent\":{}}],[\"getprojectsendedbeforedate\",{\"_index\":379,\"name\":{\"454\":{}},\"parent\":{}}],[\"getprojectsstartedafterdate\",{\"_index\":375,\"name\":{\"450\":{}},\"parent\":{}}],[\"getprojectsstartedbeforedate\",{\"_index\":376,\"name\":{\"451\":{}},\"parent\":{}}],[\"getprojectyear\",{\"_index\":382,\"name\":{\"460\":{}},\"parent\":{}}],[\"getpronouns\",{\"_index\":21,\"name\":{\"23\":{}},\"parent\":{}}],[\"getresponsibilities\",{\"_index\":27,\"name\":{\"29\":{}},\"parent\":{}}],[\"getrole\",{\"_index\":387,\"name\":{\"465\":{}},\"parent\":{}}],[\"getrolesbyname\",{\"_index\":388,\"name\":{\"466\":{}},\"parent\":{}}],[\"getrouter\",{\"_index\":4,\"name\":{\"4\":{},\"9\":{},\"13\":{},\"57\":{},\"67\":{},\"73\":{},\"79\":{},\"95\":{},\"101\":{},\"106\":{},\"114\":{},\"121\":{},\"135\":{},\"138\":{}},\"parent\":{}}],[\"getsingletemplate\",{\"_index\":108,\"name\":{\"117\":{}},\"parent\":{}}],[\"getstudent\",{\"_index\":100,\"name\":{\"108\":{},\"480\":{}},\"parent\":{}}],[\"getstudentevaluationsfinal\",{\"_index\":163,\"name\":{\"175\":{}},\"parent\":{}}],[\"getstudentevaluationstemp\",{\"_index\":164,\"name\":{\"176\":{}},\"parent\":{}}],[\"getstudentevaluationstotal\",{\"_index\":162,\"name\":{\"174\":{}},\"parent\":{}}],[\"getstudentsuggestions\",{\"_index\":103,\"name\":{\"111\":{}},\"parent\":{}}],[\"gettemplatebyid\",{\"_index\":404,\"name\":{\"489\":{}},\"parent\":{}}],[\"gettemplatesbyname\",{\"_index\":405,\"name\":{\"490\":{}},\"parent\":{}}],[\"getusersfor\",{\"_index\":366,\"name\":{\"440\":{}},\"parent\":{}}],[\"getvolunteerinfo\",{\"_index\":29,\"name\":{\"31\":{}},\"parent\":{}}],[\"getyearpermissions\",{\"_index\":124,\"name\":{\"134\":{}},\"parent\":{}}],[\"ghexchangeaccesstoken\",{\"_index\":60,\"name\":{\"63\":{}},\"parent\":{}}],[\"ghidentity\",{\"_index\":59,\"name\":{\"62\":{}},\"parent\":{}}],[\"ghsignuporlogin\",{\"_index\":63,\"name\":{\"66\":{}},\"parent\":{}}],[\"github\",{\"_index\":216,\"name\":{\"226\":{},\"232\":{}},\"parent\":{}}],[\"github_id\",{\"_index\":218,\"name\":{\"228\":{}},\"parent\":{}}],[\"githubnamechange\",{\"_index\":62,\"name\":{\"65\":{}},\"parent\":{}}],[\"information\",{\"_index\":248,\"name\":{\"274\":{},\"280\":{},\"374\":{}},\"parent\":{}}],[\"is_best\",{\"_index\":312,\"name\":{\"368\":{}},\"parent\":{}}],[\"is_coach\",{\"_index\":295,\"name\":{\"338\":{}},\"parent\":{}}],[\"isadmin\",{\"_index\":224,\"name\":{\"237\":{},\"243\":{}},\"parent\":{}}],[\"isbest\",{\"_index\":309,\"name\":{\"360\":{}},\"parent\":{}}],[\"iscoach\",{\"_index\":225,\"name\":{\"238\":{},\"244\":{}},\"parent\":{}}],[\"isfinal\",{\"_index\":243,\"name\":{\"265\":{}},\"parent\":{}}],[\"ispreferred\",{\"_index\":308,\"name\":{\"359\":{},\"367\":{}},\"parent\":{}}],[\"isstudentcoach\",{\"_index\":30,\"name\":{\"32\":{}},\"parent\":{}}],[\"jobapplicationid\",{\"_index\":240,\"name\":{\"262\":{},\"355\":{},\"363\":{},\"379\":{}},\"parent\":{}}],[\"jobapplicationskillid\",{\"_index\":310,\"name\":{\"362\":{}},\"parent\":{}}],[\"jsontoattachments\",{\"_index\":44,\"name\":{\"46\":{}},\"parent\":{}}],[\"jsontojobapplication\",{\"_index\":36,\"name\":{\"38\":{}},\"parent\":{}}],[\"jsontoperson\",{\"_index\":20,\"name\":{\"22\":{}},\"parent\":{}}],[\"jsontoroles\",{\"_index\":46,\"name\":{\"48\":{}},\"parent\":{}}],[\"jsontoskills\",{\"_index\":40,\"name\":{\"42\":{}},\"parent\":{}}],[\"jsontostudent\",{\"_index\":26,\"name\":{\"28\":{}},\"parent\":{}}],[\"languageid\",{\"_index\":303,\"name\":{\"352\":{},\"357\":{},\"365\":{}},\"parent\":{}}],[\"level\",{\"_index\":307,\"name\":{\"358\":{},\"366\":{}},\"parent\":{}}],[\"listadmins\",{\"_index\":1,\"name\":{\"1\":{}},\"parent\":{}}],[\"listcoaches\",{\"_index\":6,\"name\":{\"6\":{}},\"parent\":{}}],[\"listosoceditions\",{\"_index\":72,\"name\":{\"76\":{}},\"parent\":{}}],[\"listprojects\",{\"_index\":77,\"name\":{\"82\":{}},\"parent\":{}}],[\"liststudentroles\",{\"_index\":97,\"name\":{\"104\":{}},\"parent\":{}}],[\"listusers\",{\"_index\":114,\"name\":{\"124\":{}},\"parent\":{}}],[\"login\",{\"_index\":68,\"name\":{\"71\":{}},\"parent\":{}}],[\"login_user\",{\"_index\":291,\"name\":{\"335\":{}},\"parent\":{}}],[\"login_user_id\",{\"_index\":293,\"name\":{\"337\":{}},\"parent\":{}}],[\"loginuserid\",{\"_index\":227,\"name\":{\"241\":{},\"261\":{},\"268\":{},\"275\":{},\"279\":{},\"370\":{},\"377\":{}},\"parent\":{}}],[\"logout\",{\"_index\":69,\"name\":{\"72\":{}},\"parent\":{}}],[\"modadmin\",{\"_index\":2,\"name\":{\"2\":{}},\"parent\":{}}],[\"modcoach\",{\"_index\":7,\"name\":{\"7\":{}},\"parent\":{}}],[\"modproject\",{\"_index\":79,\"name\":{\"84\":{}},\"parent\":{}}],[\"modprojectstudent\",{\"_index\":84,\"name\":{\"89\":{}},\"parent\":{}}],[\"motivation\",{\"_index\":242,\"name\":{\"264\":{},\"270\":{}},\"parent\":{}}],[\"name\",{\"_index\":214,\"name\":{\"225\":{},\"231\":{},\"301\":{},\"309\":{},\"317\":{},\"330\":{},\"350\":{},\"353\":{},\"383\":{},\"390\":{}},\"parent\":{}}],[\"nickname\",{\"_index\":234,\"name\":{\"251\":{},\"258\":{}},\"parent\":{}}],[\"notownererror\",{\"_index\":112,\"name\":{\"122\":{}},\"parent\":{}}],[\"orm_functions/applied_role\",{\"_index\":127,\"name\":{\"139\":{}},\"parent\":{\"140\":{},\"141\":{},\"142\":{}}}],[\"orm_functions/attachment\",{\"_index\":131,\"name\":{\"143\":{}},\"parent\":{\"144\":{},\"145\":{},\"146\":{},\"147\":{}}}],[\"orm_functions/contract\",{\"_index\":136,\"name\":{\"148\":{}},\"parent\":{\"149\":{},\"150\":{},\"151\":{},\"152\":{},\"153\":{},\"154\":{},\"155\":{}}}],[\"orm_functions/evaluation\",{\"_index\":144,\"name\":{\"156\":{}},\"parent\":{\"157\":{},\"158\":{},\"159\":{},\"160\":{},\"161\":{},\"162\":{}}}],[\"orm_functions/general_purpose\",{\"_index\":151,\"name\":{\"163\":{}},\"parent\":{\"164\":{}}}],[\"orm_functions/job_application\",{\"_index\":161,\"name\":{\"173\":{}},\"parent\":{\"174\":{},\"175\":{},\"176\":{},\"177\":{},\"178\":{},\"179\":{},\"180\":{},\"181\":{},\"182\":{},\"183\":{},\"184\":{},\"185\":{},\"186\":{}}}],[\"orm_functions/job_application_skill\",{\"_index\":153,\"name\":{\"165\":{}},\"parent\":{\"166\":{},\"167\":{},\"168\":{},\"169\":{},\"170\":{},\"171\":{},\"172\":{}}}],[\"orm_functions/language\",{\"_index\":175,\"name\":{\"187\":{}},\"parent\":{\"188\":{},\"189\":{},\"190\":{},\"191\":{},\"192\":{},\"193\":{},\"194\":{}}}],[\"orm_functions/login_user\",{\"_index\":190,\"name\":{\"202\":{}},\"parent\":{\"203\":{},\"204\":{},\"205\":{},\"206\":{},\"207\":{},\"208\":{},\"209\":{},\"210\":{},\"211\":{},\"212\":{},\"213\":{},\"214\":{},\"215\":{},\"216\":{},\"217\":{},\"218\":{},\"219\":{}}}],[\"orm_functions/login_user_osoc\",{\"_index\":183,\"name\":{\"195\":{}},\"parent\":{\"196\":{},\"197\":{},\"198\":{},\"199\":{},\"200\":{},\"201\":{}}}],[\"orm_functions/orm_types\",{\"_index\":208,\"name\":{\"220\":{}},\"parent\":{\"221\":{},\"224\":{},\"229\":{},\"234\":{},\"240\":{},\"246\":{},\"253\":{},\"260\":{},\"266\":{},\"271\":{},\"277\":{},\"283\":{},\"297\":{},\"300\":{},\"307\":{},\"315\":{},\"326\":{},\"334\":{},\"339\":{},\"343\":{},\"348\":{},\"351\":{},\"354\":{},\"361\":{},\"369\":{},\"375\":{},\"378\":{},\"381\":{},\"387\":{},\"394\":{},\"395\":{},\"396\":{},\"397\":{},\"398\":{},\"399\":{}}}],[\"orm_functions/orm_types.addstudenttoproject\",{\"_index\":313,\"name\":{},\"parent\":{\"370\":{},\"371\":{},\"372\":{},\"373\":{},\"374\":{}}}],[\"orm_functions/orm_types.createappliedrole\",{\"_index\":317,\"name\":{},\"parent\":{\"379\":{},\"380\":{}}}],[\"orm_functions/orm_types.createcontract\",{\"_index\":246,\"name\":{},\"parent\":{\"272\":{},\"273\":{},\"274\":{},\"275\":{},\"276\":{}}}],[\"orm_functions/orm_types.createevaluationforstudent\",{\"_index\":239,\"name\":{},\"parent\":{\"261\":{},\"262\":{},\"263\":{},\"264\":{},\"265\":{}}}],[\"orm_functions/orm_types.createjobapplication\",{\"_index\":252,\"name\":{},\"parent\":{\"284\":{},\"285\":{},\"286\":{},\"287\":{},\"288\":{},\"289\":{},\"290\":{},\"291\":{},\"292\":{},\"293\":{},\"294\":{},\"295\":{},\"296\":{}}}],[\"orm_functions/orm_types.createjobapplicationskill\",{\"_index\":305,\"name\":{},\"parent\":{\"355\":{},\"356\":{},\"357\":{},\"358\":{},\"359\":{},\"360\":{}}}],[\"orm_functions/orm_types.createloginuser\",{\"_index\":222,\"name\":{},\"parent\":{\"235\":{},\"236\":{},\"237\":{},\"238\":{},\"239\":{}}}],[\"orm_functions/orm_types.createperson\",{\"_index\":215,\"name\":{},\"parent\":{\"225\":{},\"226\":{},\"227\":{},\"228\":{}}}],[\"orm_functions/orm_types.createproject\",{\"_index\":268,\"name\":{},\"parent\":{\"301\":{},\"302\":{},\"303\":{},\"304\":{},\"305\":{},\"306\":{}}}],[\"orm_functions/orm_types.createprojectrole\",{\"_index\":297,\"name\":{},\"parent\":{\"340\":{},\"341\":{},\"342\":{}}}],[\"orm_functions/orm_types.createstudent\",{\"_index\":230,\"name\":{},\"parent\":{\"247\":{},\"248\":{},\"249\":{},\"250\":{},\"251\":{},\"252\":{}}}],[\"orm_functions/orm_types.createtemplate\",{\"_index\":319,\"name\":{},\"parent\":{\"382\":{},\"383\":{},\"384\":{},\"385\":{},\"386\":{}}}],[\"orm_functions/orm_types.dbpagination\",{\"_index\":211,\"name\":{},\"parent\":{\"222\":{},\"223\":{}}}],[\"orm_functions/orm_types.filterprojects\",{\"_index\":277,\"name\":{},\"parent\":{\"316\":{},\"317\":{},\"318\":{},\"319\":{},\"320\":{},\"321\":{},\"322\":{},\"323\":{},\"324\":{},\"325\":{}}}],[\"orm_functions/orm_types.filterprojectsloginuser\",{\"_index\":292,\"name\":{},\"parent\":{\"335\":{},\"336\":{}}}],[\"orm_functions/orm_types.filterprojectsloginuser.__type\",{\"_index\":294,\"name\":{},\"parent\":{\"337\":{},\"338\":{}}}],[\"orm_functions/orm_types.filterprojectsrole\",{\"_index\":285,\"name\":{},\"parent\":{\"327\":{},\"328\":{},\"329\":{},\"331\":{},\"332\":{}}}],[\"orm_functions/orm_types.filterprojectsrole.__type\",{\"_index\":287,\"name\":{},\"parent\":{\"330\":{},\"333\":{}}}],[\"orm_functions/orm_types.projectuser\",{\"_index\":316,\"name\":{},\"parent\":{\"376\":{},\"377\":{}}}],[\"orm_functions/orm_types.updatecontract\",{\"_index\":251,\"name\":{},\"parent\":{\"278\":{},\"279\":{},\"280\":{},\"281\":{},\"282\":{}}}],[\"orm_functions/orm_types.updateevaluationforstudent\",{\"_index\":245,\"name\":{},\"parent\":{\"267\":{},\"268\":{},\"269\":{},\"270\":{}}}],[\"orm_functions/orm_types.updatejobapplicationskill\",{\"_index\":311,\"name\":{},\"parent\":{\"362\":{},\"363\":{},\"364\":{},\"365\":{},\"366\":{},\"367\":{},\"368\":{}}}],[\"orm_functions/orm_types.updatelanguage\",{\"_index\":304,\"name\":{},\"parent\":{\"352\":{},\"353\":{}}}],[\"orm_functions/orm_types.updateloginuser\",{\"_index\":228,\"name\":{},\"parent\":{\"241\":{},\"242\":{},\"243\":{},\"244\":{},\"245\":{}}}],[\"orm_functions/orm_types.updateosoc\",{\"_index\":266,\"name\":{},\"parent\":{\"298\":{},\"299\":{}}}],[\"orm_functions/orm_types.updateperson\",{\"_index\":221,\"name\":{},\"parent\":{\"230\":{},\"231\":{},\"232\":{},\"233\":{}}}],[\"orm_functions/orm_types.updateproject\",{\"_index\":275,\"name\":{},\"parent\":{\"308\":{},\"309\":{},\"310\":{},\"311\":{},\"312\":{},\"313\":{},\"314\":{}}}],[\"orm_functions/orm_types.updateprojectrole\",{\"_index\":300,\"name\":{},\"parent\":{\"344\":{},\"345\":{},\"346\":{},\"347\":{}}}],[\"orm_functions/orm_types.updaterole\",{\"_index\":302,\"name\":{},\"parent\":{\"349\":{},\"350\":{}}}],[\"orm_functions/orm_types.updatestudent\",{\"_index\":238,\"name\":{},\"parent\":{\"254\":{},\"255\":{},\"256\":{},\"257\":{},\"258\":{},\"259\":{}}}],[\"orm_functions/orm_types.updatetemplate\",{\"_index\":324,\"name\":{},\"parent\":{\"388\":{},\"389\":{},\"390\":{},\"391\":{},\"392\":{},\"393\":{}}}],[\"orm_functions/osoc\",{\"_index\":331,\"name\":{\"400\":{}},\"parent\":{\"401\":{},\"402\":{},\"403\":{},\"404\":{},\"405\":{},\"406\":{},\"407\":{},\"408\":{},\"409\":{},\"410\":{},\"411\":{},\"412\":{},\"413\":{}}}],[\"orm_functions/password_reset\",{\"_index\":344,\"name\":{\"414\":{}},\"parent\":{\"415\":{},\"416\":{},\"417\":{},\"418\":{}}}],[\"orm_functions/person\",{\"_index\":349,\"name\":{\"419\":{}},\"parent\":{\"420\":{},\"421\":{},\"422\":{},\"423\":{},\"424\":{},\"425\":{},\"426\":{},\"427\":{},\"428\":{}}}],[\"orm_functions/project\",{\"_index\":368,\"name\":{\"442\":{}},\"parent\":{\"443\":{},\"444\":{},\"445\":{},\"446\":{},\"447\":{},\"448\":{},\"449\":{},\"450\":{},\"451\":{},\"452\":{},\"453\":{},\"454\":{},\"455\":{},\"456\":{},\"457\":{},\"458\":{},\"459\":{},\"460\":{},\"461\":{}}}],[\"orm_functions/project_role\",{\"_index\":357,\"name\":{\"429\":{}},\"parent\":{\"430\":{},\"431\":{},\"432\":{},\"433\":{},\"434\":{},\"435\":{},\"436\":{},\"437\":{}}}],[\"orm_functions/project_user\",{\"_index\":364,\"name\":{\"438\":{}},\"parent\":{\"439\":{},\"440\":{},\"441\":{}}}],[\"orm_functions/role\",{\"_index\":384,\"name\":{\"462\":{}},\"parent\":{\"463\":{},\"464\":{},\"465\":{},\"466\":{},\"467\":{},\"468\":{},\"469\":{},\"470\":{}}}],[\"orm_functions/session_key\",{\"_index\":392,\"name\":{\"471\":{}},\"parent\":{\"472\":{},\"473\":{},\"474\":{},\"475\":{},\"476\":{}}}],[\"orm_functions/student\",{\"_index\":398,\"name\":{\"477\":{}},\"parent\":{\"478\":{},\"479\":{},\"480\":{},\"481\":{},\"482\":{},\"483\":{},\"484\":{},\"485\":{},\"486\":{}}}],[\"orm_functions/template\",{\"_index\":403,\"name\":{\"487\":{}},\"parent\":{\"488\":{},\"489\":{},\"490\":{},\"491\":{},\"492\":{},\"493\":{}}}],[\"osoc_id\",{\"_index\":278,\"name\":{\"318\":{}},\"parent\":{}}],[\"osocid\",{\"_index\":257,\"name\":{\"289\":{},\"298\":{},\"302\":{},\"310\":{}},\"parent\":{}}],[\"ownerid\",{\"_index\":318,\"name\":{\"382\":{},\"389\":{}},\"parent\":{}}],[\"pagesize\",{\"_index\":212,\"name\":{\"223\":{}},\"parent\":{}}],[\"parseghlogin\",{\"_index\":61,\"name\":{\"64\":{}},\"parent\":{}}],[\"partner\",{\"_index\":269,\"name\":{\"303\":{},\"311\":{},\"319\":{}},\"parent\":{}}],[\"password\",{\"_index\":223,\"name\":{\"236\":{},\"242\":{}},\"parent\":{}}],[\"personid\",{\"_index\":220,\"name\":{\"230\":{},\"235\":{},\"247\":{}},\"parent\":{}}],[\"phonenumber\",{\"_index\":233,\"name\":{\"250\":{},\"257\":{}},\"parent\":{}}],[\"positions\",{\"_index\":281,\"name\":{\"322\":{},\"327\":{},\"342\":{},\"347\":{}},\"parent\":{}}],[\"project_id\",{\"_index\":276,\"name\":{\"316\":{}},\"parent\":{}}],[\"project_role\",{\"_index\":282,\"name\":{\"324\":{}},\"parent\":{}}],[\"project_user\",{\"_index\":283,\"name\":{\"325\":{}},\"parent\":{}}],[\"projectid\",{\"_index\":274,\"name\":{\"308\":{},\"340\":{},\"345\":{},\"372\":{},\"376\":{}},\"parent\":{}}],[\"projectroleid\",{\"_index\":247,\"name\":{\"273\":{},\"282\":{},\"344\":{}},\"parent\":{}}],[\"projectuser\",{\"_index\":315,\"name\":{\"375\":{}},\"parent\":{}}],[\"pronouns\",{\"_index\":232,\"name\":{\"249\":{},\"256\":{}},\"parent\":{}}],[\"readfile\",{\"_index\":54,\"name\":{\"56\":{}},\"parent\":{}}],[\"refreshkey\",{\"_index\":395,\"name\":{\"474\":{}},\"parent\":{}}],[\"removeallkeysforloginuserid\",{\"_index\":397,\"name\":{\"476\":{}},\"parent\":{}}],[\"removeallkeysforuser\",{\"_index\":396,\"name\":{\"475\":{}},\"parent\":{}}],[\"removecontract\",{\"_index\":140,\"name\":{\"152\":{}},\"parent\":{}}],[\"removecontractsfromstudent\",{\"_index\":139,\"name\":{\"151\":{}},\"parent\":{}}],[\"removeosocfromuser\",{\"_index\":188,\"name\":{\"200\":{}},\"parent\":{}}],[\"requestreset\",{\"_index\":92,\"name\":{\"98\":{}},\"parent\":{}}],[\"resetpassword\",{\"_index\":94,\"name\":{\"100\":{}},\"parent\":{}}],[\"responsibilities\",{\"_index\":253,\"name\":{\"285\":{}},\"parent\":{}}],[\"role\",{\"_index\":286,\"name\":{\"328\":{}},\"parent\":{}}],[\"roleid\",{\"_index\":298,\"name\":{\"341\":{},\"346\":{},\"349\":{},\"380\":{}},\"parent\":{}}],[\"rolename\",{\"_index\":314,\"name\":{\"373\":{}},\"parent\":{}}],[\"routes/admin\",{\"_index\":0,\"name\":{\"0\":{}},\"parent\":{\"1\":{},\"2\":{},\"3\":{},\"4\":{}}}],[\"routes/coach\",{\"_index\":5,\"name\":{\"5\":{}},\"parent\":{\"6\":{},\"7\":{},\"8\":{},\"9\":{}}}],[\"routes/followup\",{\"_index\":9,\"name\":{\"10\":{}},\"parent\":{\"11\":{},\"12\":{},\"13\":{}}}],[\"routes/form\",{\"_index\":12,\"name\":{\"14\":{}},\"parent\":{\"15\":{},\"16\":{},\"17\":{},\"18\":{},\"19\":{},\"20\":{},\"21\":{},\"22\":{},\"23\":{},\"24\":{},\"25\":{},\"26\":{},\"27\":{},\"28\":{},\"29\":{},\"30\":{},\"31\":{},\"32\":{},\"33\":{},\"34\":{},\"35\":{},\"36\":{},\"37\":{},\"38\":{},\"39\":{},\"40\":{},\"41\":{},\"42\":{},\"43\":{},\"44\":{},\"45\":{},\"46\":{},\"47\":{},\"48\":{},\"49\":{},\"50\":{},\"51\":{},\"52\":{},\"53\":{},\"54\":{},\"55\":{},\"56\":{},\"57\":{}}}],[\"routes/github\",{\"_index\":55,\"name\":{\"58\":{}},\"parent\":{\"59\":{},\"60\":{},\"61\":{},\"62\":{},\"63\":{},\"64\":{},\"65\":{},\"66\":{},\"67\":{},\"68\":{}}}],[\"routes/github.states\",{\"_index\":66,\"name\":{},\"parent\":{\"69\":{}}}],[\"routes/login\",{\"_index\":67,\"name\":{\"70\":{}},\"parent\":{\"71\":{},\"72\":{},\"73\":{}}}],[\"routes/osoc\",{\"_index\":70,\"name\":{\"74\":{}},\"parent\":{\"75\":{},\"76\":{},\"77\":{},\"78\":{},\"79\":{}}}],[\"routes/project\",{\"_index\":75,\"name\":{\"80\":{}},\"parent\":{\"81\":{},\"82\":{},\"83\":{},\"84\":{},\"85\":{},\"86\":{},\"87\":{},\"88\":{},\"89\":{},\"90\":{},\"91\":{},\"92\":{},\"93\":{},\"94\":{},\"95\":{}}}],[\"routes/reset\",{\"_index\":90,\"name\":{\"96\":{}},\"parent\":{\"97\":{},\"98\":{},\"99\":{},\"100\":{},\"101\":{},\"102\":{}}}],[\"routes/role\",{\"_index\":96,\"name\":{\"103\":{}},\"parent\":{\"104\":{},\"105\":{},\"106\":{}}}],[\"routes/student\",{\"_index\":99,\"name\":{\"107\":{}},\"parent\":{\"108\":{},\"109\":{},\"110\":{},\"111\":{},\"112\":{},\"113\":{},\"114\":{}}}],[\"routes/template\",{\"_index\":106,\"name\":{\"115\":{}},\"parent\":{\"116\":{},\"117\":{},\"118\":{},\"119\":{},\"120\":{},\"121\":{},\"122\":{}}}],[\"routes/user\",{\"_index\":113,\"name\":{\"123\":{}},\"parent\":{\"124\":{},\"125\":{},\"126\":{},\"127\":{},\"128\":{},\"129\":{},\"130\":{},\"131\":{},\"132\":{},\"133\":{},\"134\":{},\"135\":{}}}],[\"routes/verify\",{\"_index\":125,\"name\":{\"136\":{}},\"parent\":{\"137\":{},\"138\":{}}}],[\"searchalladminandcoachloginusers\",{\"_index\":198,\"name\":{\"210\":{}},\"parent\":{}}],[\"searchalladminloginusers\",{\"_index\":196,\"name\":{\"208\":{}},\"parent\":{}}],[\"searchallcoachloginusers\",{\"_index\":197,\"name\":{\"209\":{}},\"parent\":{}}],[\"searchloginuserbyperson\",{\"_index\":195,\"name\":{\"207\":{}},\"parent\":{}}],[\"searchpersonbylogin\",{\"_index\":354,\"name\":{\"425\":{}},\"parent\":{}}],[\"searchpersonbyname\",{\"_index\":353,\"name\":{\"424\":{}},\"parent\":{}}],[\"searchstudentbygender\",{\"_index\":401,\"name\":{\"484\":{}},\"parent\":{}}],[\"sendmail\",{\"_index\":91,\"name\":{\"97\":{}},\"parent\":{}}],[\"setaccountstatus\",{\"_index\":116,\"name\":{\"126\":{}},\"parent\":{}}],[\"setadmin\",{\"_index\":206,\"name\":{\"218\":{}},\"parent\":{}}],[\"setcoach\",{\"_index\":205,\"name\":{\"217\":{}},\"parent\":{}}],[\"skill\",{\"_index\":306,\"name\":{\"356\":{},\"364\":{}},\"parent\":{}}],[\"sortedcontractsbyosocedition\",{\"_index\":143,\"name\":{\"155\":{}},\"parent\":{}}],[\"start_date\",{\"_index\":279,\"name\":{\"320\":{}},\"parent\":{}}],[\"startdate\",{\"_index\":270,\"name\":{\"304\":{},\"312\":{}},\"parent\":{}}],[\"states\",{\"_index\":64,\"name\":{\"68\":{}},\"parent\":{}}],[\"studentcoach\",{\"_index\":256,\"name\":{\"288\":{}},\"parent\":{}}],[\"studentid\",{\"_index\":237,\"name\":{\"254\":{},\"272\":{},\"284\":{},\"371\":{}},\"parent\":{}}],[\"studentvolunteerinfo\",{\"_index\":255,\"name\":{\"287\":{}},\"parent\":{}}],[\"subject\",{\"_index\":321,\"name\":{\"385\":{},\"392\":{}},\"parent\":{}}],[\"templateid\",{\"_index\":323,\"name\":{\"388\":{}},\"parent\":{}}],[\"unassigncoach\",{\"_index\":85,\"name\":{\"90\":{}},\"parent\":{}}],[\"unassignstudent\",{\"_index\":87,\"name\":{\"92\":{}},\"parent\":{}}],[\"updatecontract\",{\"_index\":138,\"name\":{\"150\":{},\"277\":{}},\"parent\":{}}],[\"updateevaluationforstudent\",{\"_index\":147,\"name\":{\"159\":{},\"266\":{}},\"parent\":{}}],[\"updatefollowup\",{\"_index\":11,\"name\":{\"12\":{}},\"parent\":{}}],[\"updatejobapplicationskill\",{\"_index\":158,\"name\":{\"170\":{},\"361\":{}},\"parent\":{}}],[\"updatelanguage\",{\"_index\":180,\"name\":{\"192\":{},\"351\":{}},\"parent\":{}}],[\"updateloginuser\",{\"_index\":199,\"name\":{\"211\":{},\"240\":{}},\"parent\":{}}],[\"updateosoc\",{\"_index\":265,\"name\":{\"297\":{},\"407\":{}},\"parent\":{}}],[\"updateperson\",{\"_index\":219,\"name\":{\"229\":{},\"426\":{}},\"parent\":{}}],[\"updateproject\",{\"_index\":273,\"name\":{\"307\":{},\"455\":{}},\"parent\":{}}],[\"updateprojectrole\",{\"_index\":299,\"name\":{\"343\":{},\"434\":{}},\"parent\":{}}],[\"updaterole\",{\"_index\":301,\"name\":{\"348\":{},\"468\":{}},\"parent\":{}}],[\"updatestudent\",{\"_index\":236,\"name\":{\"253\":{},\"481\":{}},\"parent\":{}}],[\"updatetemplate\",{\"_index\":110,\"name\":{\"119\":{},\"387\":{},\"492\":{}},\"parent\":{}}],[\"usermodself\",{\"_index\":120,\"name\":{\"130\":{}},\"parent\":{}}],[\"verifykey\",{\"_index\":126,\"name\":{\"137\":{}},\"parent\":{}}],[\"year\",{\"_index\":267,\"name\":{\"299\":{}},\"parent\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file diff --git a/backend/docs/index.html b/backend/docs/index.html index 2118b236..6252e415 100644 --- a/backend/docs/index.html +++ b/backend/docs/index.html @@ -23,4 +23,4 @@

Team 2:

  • Jonathan Vanbrabant
  • Maurice Van Wassenhove
  • -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.AddStudentToProject.html b/backend/docs/interfaces/orm_functions_orm_types.AddStudentToProject.html index cb4860b3..cee2b276 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.AddStudentToProject.html +++ b/backend/docs/interfaces/orm_functions_orm_types.AddStudentToProject.html @@ -1,11 +1,11 @@ -AddStudentToProject | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Hierarchy

    • AddStudentToProject

    Index

    Properties

    information?: null | string
    +AddStudentToProject | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Hierarchy

    • AddStudentToProject

    Index

    Properties

    information?: null | string

    extra information

    -
    loginUserId: number
    +
    loginUserId: number

    the id of the loginsuer that wants to add a student to the project

    -
    projectId: number
    +
    projectId: number

    the id of the project that the student will be added to

    -
    roleName: string
    +
    roleName: string

    the name of the role the student will be added for

    -
    studentId: number
    +
    studentId: number

    the id of the student that will be added to the project

    -

    Legend

    • Variable
    • Function
    • Type alias
    • Interface
    • Property

    Settings

    Theme

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateAppliedRole.html b/backend/docs/interfaces/orm_functions_orm_types.CreateAppliedRole.html index 48712399..0cb4f33b 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateAppliedRole.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateAppliedRole.html @@ -1,7 +1,7 @@ CreateAppliedRole | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateContract.html b/backend/docs/interfaces/orm_functions_orm_types.CreateContract.html index afe46df1..43875375 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateContract.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateContract.html @@ -1,13 +1,13 @@ CreateContract | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed in createContract

    -

    Hierarchy

    • CreateContract

    Index

    Properties

    contractStatus: contract_status_enum
    +

    Hierarchy

    • CreateContract

    Index

    Properties

    contractStatus: contract_status_enum

    status of the contract (draft, approved, cancelled,...)

    -
    information?: null | string
    +
    information?: null | string

    extra information

    -
    loginUserId: number
    +
    loginUserId: number

    the loginUser that created this contract

    -
    projectRoleId: number
    +
    projectRoleId: number

    the role for which the contract is

    -
    studentId: number
    +
    studentId: number

    the student that receives the contract

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html b/backend/docs/interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html index d9d91a5d..42e812a9 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateEvaluationForStudent.html @@ -1,13 +1,13 @@ CreateEvaluationForStudent | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed in createEvaluationForStudent

    -

    Hierarchy

    • CreateEvaluationForStudent

    Index

    Properties

    decision: decision_enum
    +

    Hierarchy

    • CreateEvaluationForStudent

    Index

    Properties

    decision: decision_enum

    the decision that is made (yes, maybe, no)

    -
    isFinal: boolean
    +
    isFinal: boolean

    is this evaluation final, or not

    -
    jobApplicationId: number
    +
    jobApplicationId: number

    the jobApplication about that the evaluation is about

    -
    loginUserId: number
    +
    loginUserId: number

    loginUserId of the loginUser that creates this evaluation

    -
    motivation?: null | string
    +
    motivation?: null | string

    motivation for the made decision

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplication.html b/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplication.html index 5ab791fb..bb22cfbc 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplication.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplication.html @@ -1,29 +1,29 @@ CreateJobApplication | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed in createJobApplication

    -

    Hierarchy

    • CreateJobApplication

    Index

    Properties

    createdAt: string
    +

    Hierarchy

    • CreateJobApplication

    Index

    Properties

    createdAt: string

    keeps track of when we received this application (used to pick the latest one)

    -
    eduDuration: null | number
    +
    eduDuration: null | number

    how long this student has been studying for

    -
    eduInstitute: null | string
    +
    eduInstitute: null | string

    institute the student is studying at

    -
    eduLevel: string
    +
    eduLevel: string

    information about the education level of the student

    -
    eduYear: null | string
    +
    eduYear: null | string

    expected graduation year

    -
    edus: string[]
    +
    edus: string[]

    information about the educations of the student

    -
    emailStatus: email_status_enum
    +
    emailStatus: email_status_enum

    information about a confirmation email for the evaluation

    -
    funFact: string
    +
    funFact: string

    a fun fact about the student

    -
    osocId: number
    +
    osocId: number

    id of the osoc edition this job application is for

    -
    responsibilities?: null | string
    +
    responsibilities?: null | string

    the responsibilities the students has during the summer that might keep him from working for osoc

    -
    studentCoach: boolean
    +
    studentCoach: boolean

    boolean that indicates if the student is a student-coach or not

    -
    studentId: number
    +
    studentId: number

    the student who's application this is

    -
    studentVolunteerInfo: string
    +
    studentVolunteerInfo: string

    string that has info if the student is available to work, and if he wants to work as volunteer for free or not

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html b/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html index b7e64096..8e3e3c93 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateJobApplicationSkill.html @@ -1,15 +1,15 @@ CreateJobApplicationSkill | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to create a project

    -

    Hierarchy

    • CreateJobApplicationSkill

    Index

    Properties

    isBest: boolean
    +

    Hierarchy

    • CreateJobApplicationSkill

    Index

    Properties

    isBest: boolean

    true if this skill is the best skill of the applicant

    -
    isPreferred: boolean
    +
    isPreferred: boolean

    true if this skill is the preffered skill of the applicant

    -
    jobApplicationId: number
    +
    jobApplicationId: number

    the jobapplicaton id to which the skill is linked

    -
    languageId: null | number
    +
    languageId: null | number

    the language id to which this skill is linked

    -
    level: null | number
    +
    level: null | number

    the level of the skill of the applicant

    -
    skill: null | string
    +
    skill: null | string

    the skill of this job application

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateLoginUser.html b/backend/docs/interfaces/orm_functions_orm_types.CreateLoginUser.html index 961a7bbb..1183f716 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateLoginUser.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateLoginUser.html @@ -1,13 +1,13 @@ CreateLoginUser | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to create a login user

    -

    Hierarchy

    • CreateLoginUser

    Index

    Properties

    accountStatus: account_status_enum
    +

    Hierarchy

    • CreateLoginUser

    Index

    Properties

    accountStatus: account_status_enum

    the status of the account we are trying to create

    -
    isAdmin: boolean
    +
    isAdmin: boolean

    true if the login user is an admin in the osoc system, otherwise false

    -
    isCoach: boolean
    +
    isCoach: boolean

    true if the login user is a coach in the osoc system, otherwise false

    -
    password?: null | string
    +
    password?: null | string

    the password hash of the login user if email is used

    -
    personId: number
    +
    personId: number

    the person_id of the person the login user will be associated with

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreatePerson.html b/backend/docs/interfaces/orm_functions_orm_types.CreatePerson.html index b2003004..9490ac7a 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreatePerson.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreatePerson.html @@ -1,13 +1,11 @@ CreatePerson | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to create a person

    -

    Hierarchy

    • CreatePerson

    Index

    Properties

    email?: string
    +

    Hierarchy

    • CreatePerson

    Index

    Properties

    email?: string

    the person's email, may not be null if github is null

    -
    firstname: string
    -

    the person's firstname

    -
    github?: string
    +
    github?: string

    the person's github account, only one of github/email can be used

    -
    github_id?: string
    +
    github_id?: string

    the person's github id, if github is used

    -
    lastname: string
    -

    the person's lastname

    -

    Generated using TypeDoc

    \ No newline at end of file +
    name: string
    +

    the person's name

    +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateProject.html b/backend/docs/interfaces/orm_functions_orm_types.CreateProject.html index 3cb39bf5..e732e5fc 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateProject.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateProject.html @@ -1,15 +1,15 @@ CreateProject | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to create a project

    -

    Hierarchy

    • CreateProject

    Index

    Properties

    endDate: Date
    +

    Hierarchy

    • CreateProject

    Index

    Properties

    description: string
    +

    a short description of the project

    +
    endDate: Date

    the end date of the project

    -
    name: string
    +
    name: string

    the name of the project

    -
    osocId: number
    +
    osocId: number

    the id of the osoc edition this project belongs to

    -
    partner: string
    +
    partner: string

    the partner for who this project is made

    -
    positions: number
    -

    the amount of people who need to assigned to the project

    -
    startDate: Date
    +
    startDate: Date

    the start date of the project

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateProjectRole.html b/backend/docs/interfaces/orm_functions_orm_types.CreateProjectRole.html index a4ceae74..6133b278 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateProjectRole.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateProjectRole.html @@ -1,9 +1,9 @@ CreateProjectRole | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateProjectUser.html b/backend/docs/interfaces/orm_functions_orm_types.CreateProjectUser.html deleted file mode 100644 index 50c851b5..00000000 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateProjectUser.html +++ /dev/null @@ -1,7 +0,0 @@ -CreateProjectUser | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateStudent.html b/backend/docs/interfaces/orm_functions_orm_types.CreateStudent.html index b65c2f5d..6c0030af 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateStudent.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateStudent.html @@ -1,15 +1,15 @@ CreateStudent | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to create a student

    -

    Hierarchy

    • CreateStudent

    Index

    Properties

    alumni: boolean
    +

    Hierarchy

    • CreateStudent

    Index

    Properties

    alumni: boolean

    true if the student is an alumni in the osoc system, otherwise false

    -
    gender: string
    +
    gender: string

    the person's gender

    -
    nickname?: null | string
    +
    nickname?: null | string

    student's nickname

    -
    personId?: number
    +
    personId?: number

    the person_id of the person the student will be associated with

    -
    phoneNumber: string
    +
    phoneNumber: string

    student's phone number

    -
    pronouns?: null | string
    +
    pronouns?: null | string

    the pronouns the student wants to be addressed with

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.CreateTemplate.html b/backend/docs/interfaces/orm_functions_orm_types.CreateTemplate.html index ca311984..9f716946 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.CreateTemplate.html +++ b/backend/docs/interfaces/orm_functions_orm_types.CreateTemplate.html @@ -1 +1 @@ -CreateTemplate | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file +CreateTemplate | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.DBPagination.html b/backend/docs/interfaces/orm_functions_orm_types.DBPagination.html new file mode 100644 index 00000000..1eed392f --- /dev/null +++ b/backend/docs/interfaces/orm_functions_orm_types.DBPagination.html @@ -0,0 +1 @@ +DBPagination | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.FilterProjects.html b/backend/docs/interfaces/orm_functions_orm_types.FilterProjects.html new file mode 100644 index 00000000..e7233adf --- /dev/null +++ b/backend/docs/interfaces/orm_functions_orm_types.FilterProjects.html @@ -0,0 +1,23 @@ +FilterProjects | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu
    +

    interface for the filtered projects

    +

    Hierarchy

    • FilterProjects

    Index

    Properties

    description: string
    +

    the description of this project

    +
    end_date: Date
    +

    the end date of the project

    +
    name: string
    +

    the name of the project

    +
    osoc_id: number
    +

    the id of the osoc edition this project belongs to

    +
    partner: string
    +

    the partner of this project

    +
    positions: number
    +

    the amount of people who need to assigned to the project

    +
    project_id: number
    +

    the id of the project

    +
    project_role: FilterProjectsRole[]
    +

    the roles of this project

    +
    project_user: FilterProjectsLoginUser[]
    +

    the users who belong to this project

    +
    start_date: Date
    +

    the start date of the project

    +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html b/backend/docs/interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html new file mode 100644 index 00000000..14c08082 --- /dev/null +++ b/backend/docs/interfaces/orm_functions_orm_types.FilterProjectsLoginUser.html @@ -0,0 +1,5 @@ +FilterProjectsLoginUser | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.FilterProjectsRole.html b/backend/docs/interfaces/orm_functions_orm_types.FilterProjectsRole.html new file mode 100644 index 00000000..b56e75ca --- /dev/null +++ b/backend/docs/interfaces/orm_functions_orm_types.FilterProjectsRole.html @@ -0,0 +1,7 @@ +FilterProjectsRole | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.ProjectUser.html b/backend/docs/interfaces/orm_functions_orm_types.ProjectUser.html new file mode 100644 index 00000000..3ed9c6ff --- /dev/null +++ b/backend/docs/interfaces/orm_functions_orm_types.ProjectUser.html @@ -0,0 +1,7 @@ +ProjectUser | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateContract.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateContract.html index ac962625..fd43c19b 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateContract.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateContract.html @@ -1,13 +1,13 @@ UpdateContract | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed in updateContract

    -

    Hierarchy

    • UpdateContract

    Index

    Properties

    contractId: number
    +

    Hierarchy

    • UpdateContract

    Index

    Properties

    contractId: number

    the contract we are changing

    -
    contractStatus?: contract_status_enum
    +
    contractStatus?: contract_status_enum

    status of the contract (draft, approved, cancelled,...)

    -
    information?: null | string
    +
    information?: null | string

    optional information

    -
    loginUserId: number
    +
    loginUserId: number

    id of the login user that is making these changes

    -
    projectRoleId?: number
    +
    projectRoleId?: number

    updated role (id) for the student

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html index fb1dffc1..6e7511f0 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateEvaluationForStudent.html @@ -1,11 +1,11 @@ UpdateEvaluationForStudent | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed in updateEvaluationForStudent

    -

    Hierarchy

    • UpdateEvaluationForStudent

    Index

    Properties

    decision?: decision_enum
    +

    Hierarchy

    • UpdateEvaluationForStudent

    Index

    Properties

    decision?: decision_enum

    the decision that is made (yes, maybe, no)

    -
    evaluation_id: number
    +
    evaluation_id: number

    the evaluation that we are updating

    -
    loginUserId: number
    +
    loginUserId: number

    loginUserId of the loginUser that creates this evaluation

    -
    motivation?: null | string
    +
    motivation?: null | string

    motivation for the made decision

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html index edea8eff..d93b494b 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateJobApplicationSkill.html @@ -1,17 +1,17 @@ UpdateJobApplicationSkill | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to update a job application skill's data

    -

    Hierarchy

    • UpdateJobApplicationSkill

    Index

    Properties

    JobApplicationId: number
    +

    Hierarchy

    • UpdateJobApplicationSkill

    Index

    Properties

    JobApplicationId: number

    undefined if unchanged or new job application

    -
    JobApplicationSkillId: number
    +
    JobApplicationSkillId: number

    the jobapplicaton we are updating

    -
    isPreferred: boolean
    +
    isPreferred: boolean

    undefined if unchanged or the new preffered status

    -
    is_best: boolean
    +
    is_best: boolean

    undefined if unchanged or the new is best status

    -
    languageId: null | number
    +
    languageId: null | number

    undefined if unchanged or the new language of the job application skill

    -
    level: number
    +
    level: number

    undefined if unchanged or the new level

    -
    skill: null | string
    +
    skill: null | string

    undefined if unchanged or the new skill

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateLanguage.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateLanguage.html index e8fc960c..dd451d64 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateLanguage.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateLanguage.html @@ -1,7 +1,7 @@ UpdateLanguage | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateLoginUser.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateLoginUser.html index 4bf2483b..4190199f 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateLoginUser.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateLoginUser.html @@ -1,13 +1,13 @@ UpdateLoginUser | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to update a login user's data

    -

    Hierarchy

    • UpdateLoginUser

    Index

    Properties

    accountStatus: account_status_enum
    +

    Hierarchy

    • UpdateLoginUser

    Index

    Properties

    accountStatus: account_status_enum

    undefined if unchanged or the new account status that indicates the login user status

    -
    isAdmin?: boolean
    +
    isAdmin?: boolean

    undefined if unchanged or the new boolean value that indicates if this login user is an admin

    -
    isCoach?: boolean
    +
    isCoach?: boolean

    undefined if unchanged or the new boolean value that indicates if this login user is a coach

    -
    loginUserId: number
    +
    loginUserId: number

    the login user who's info we are updating

    -
    password?: null | string
    +
    password?: null | string

    undefined if unchanged or the new password

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateOsoc.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateOsoc.html index d586bba5..a1333cca 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateOsoc.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateOsoc.html @@ -1,7 +1,7 @@ UpdateOsoc | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdatePerson.html b/backend/docs/interfaces/orm_functions_orm_types.UpdatePerson.html index efd1a99a..e1c1d751 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdatePerson.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdatePerson.html @@ -1,13 +1,11 @@ UpdatePerson | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to update a person's data

    -

    Hierarchy

    • UpdatePerson

    Index

    Properties

    email?: null | string
    +

    Hierarchy

    • UpdatePerson

    Index

    Properties

    email?: null | string

    undefined if unchanged or the new email

    -
    firstname?: string
    -

    undefined if unchanged or new firstname

    -
    github?: null | string
    +
    github?: null | string

    undefined if unchanged or the new github

    -
    lastname?: string
    -

    undefined if unchanged or the new lastname

    -
    personId: number
    -

    the person who's info we are updating

    -

    Generated using TypeDoc

    \ No newline at end of file +
    name?: string
    +

    undefined if unchanged or new name

    +
    personId: number
    +

    the person whose info we are updating

    +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateProject.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateProject.html index f7f8102b..ca15138f 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateProject.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateProject.html @@ -1,17 +1,17 @@ UpdateProject | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to update a project's data

    -

    Hierarchy

    • UpdateProject

    Index

    Properties

    endDate?: Date
    +

    Hierarchy

    • UpdateProject

    Index

    Properties

    description?: string
    +

    undefined if unchanged or the new description of the project

    +
    endDate?: Date

    undefined if unchanged or the new end date of the project

    -
    name?: string
    +
    name?: string

    undefined if unchanged or new project name

    -
    osocId?: number
    +
    osocId?: number

    undefined if unchanged or the new osoc id

    -
    partner?: string
    +
    partner?: string

    undefined if unchanged or the new partner of the project

    -
    positions?: number
    -

    undefined if unchanged or the new number of positions of the project

    -
    projectId: number
    +
    projectId: number

    the project we are updating

    -
    startDate?: Date
    +
    startDate?: Date

    undefined if unchanged or the new start date of the project

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateProjectRole.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateProjectRole.html index 5895b73a..1f56306f 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateProjectRole.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateProjectRole.html @@ -1,11 +1,11 @@ UpdateProjectRole | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to update a project's data

    -

    Hierarchy

    • UpdateProjectRole

    Index

    Properties

    positions: number
    +

    Hierarchy

    • UpdateProjectRole

    Index

    Properties

    positions: number

    undefined if unchanged or the new number of positions for this role in the project

    -
    projectId: number
    +
    projectId: number

    undefined if unchanged or the new project id

    -
    projectRoleId: number
    +
    projectRoleId: number

    the project we are updating

    -
    roleId: number
    +
    roleId: number

    undefined if unchanged or the new role id

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateRole.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateRole.html index a5189a05..60d2619f 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateRole.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateRole.html @@ -1,7 +1,7 @@ UpdateRole | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateStudent.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateStudent.html index c9d939ea..bada45b0 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateStudent.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateStudent.html @@ -1,15 +1,15 @@ UpdateStudent | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    interface for the object needed to update a student's data

    -

    Hierarchy

    • UpdateStudent

    Index

    Properties

    alumni?: boolean
    +

    Hierarchy

    • UpdateStudent

    Index

    Properties

    alumni?: boolean

    undefined if unchanged or the new boolean value that indicates if this student is an alumni

    -
    gender?: string
    +
    gender?: string

    undefined if unchanged or the new gender

    -
    nickname?: null | string
    +
    nickname?: null | string

    undefined if unchanged or the new nickname

    -
    phoneNumber?: string
    +
    phoneNumber?: string

    undefined if unchanged or the new phone number

    -
    pronouns?: null | string
    +
    pronouns?: null | string

    undefined if unchanged or new list of pronouns

    -
    studentId: number
    +
    studentId: number

    the student who's info we are updating

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/interfaces/orm_functions_orm_types.UpdateTemplate.html b/backend/docs/interfaces/orm_functions_orm_types.UpdateTemplate.html index 77871852..e68556e3 100644 --- a/backend/docs/interfaces/orm_functions_orm_types.UpdateTemplate.html +++ b/backend/docs/interfaces/orm_functions_orm_types.UpdateTemplate.html @@ -1 +1 @@ -UpdateTemplate | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file +UpdateTemplate | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules.html b/backend/docs/modules.html index e636153d..3de3c252 100644 --- a/backend/docs/modules.html +++ b/backend/docs/modules.html @@ -1 +1 @@ -backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    backend

    Generated using TypeDoc

    \ No newline at end of file +backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    backend

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_applied_role.html b/backend/docs/modules/orm_functions_applied_role.html index 87c266ac..c545ac81 100644 --- a/backend/docs/modules/orm_functions_applied_role.html +++ b/backend/docs/modules/orm_functions_applied_role.html @@ -1,3 +1,3 @@ -orm_functions/applied_role | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/applied_role

    Index

    Functions

    • deleteAppliedRolesByJobApplication(jobApplicationId: number): Promise<BatchPayload>
    • getAppliedRolesByJobApplication(jobApplicationId: number): Promise<applied_role[]>

    Generated using TypeDoc

    \ No newline at end of file +orm_functions/applied_role | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/applied_role

    Index

    Functions

    • deleteAppliedRolesByJobApplication(jobApplicationId: number): Promise<BatchPayload>
    • getAppliedRolesByJobApplication(jobApplicationId: number): Promise<applied_role[]>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_attachment.html b/backend/docs/modules/orm_functions_attachment.html index da457824..a0bf21f1 100644 --- a/backend/docs/modules/orm_functions_attachment.html +++ b/backend/docs/modules/orm_functions_attachment.html @@ -1,9 +1,9 @@ -orm_functions/attachment | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/attachment

    Index

    Functions

    • createAttachment(jobApplicationId: number, data: string[], type: type_enum[]): Promise<attachment>
    • deleteAttachment(attachmentId: number): Promise<attachment>
    • getAttachmentById(attachmentId: number): Promise<null | attachment>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_contract.html b/backend/docs/modules/orm_functions_contract.html index 22302f20..000c3607 100644 --- a/backend/docs/modules/orm_functions_contract.html +++ b/backend/docs/modules/orm_functions_contract.html @@ -1,18 +1,18 @@ -orm_functions/contract | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/contract

    Index

    Functions

    • contractsByProject(projectId: number): Promise<{ contract_id: number; contract_status: contract_status_enum; project_role: project_role; student: { alumni: boolean; gender: string; nickname: null | string; person: person; phone_number: string; pronouns: null | string; student_id: number } }[]>
    • Parameters

      • projectId: number

      Returns Promise<{ contract_id: number; contract_status: contract_status_enum; project_role: project_role; student: { alumni: boolean; gender: string; nickname: null | string; person: person; phone_number: string; pronouns: null | string; student_id: number } }[]>

    • contractsForStudent(studentId: number): Promise<{ contract_id: number; project_role: { project: { osoc_id: number }; project_id: number }; student: student }[]>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_evaluation.html b/backend/docs/modules/orm_functions_evaluation.html index 6e649da0..35f5a59d 100644 --- a/backend/docs/modules/orm_functions_evaluation.html +++ b/backend/docs/modules/orm_functions_evaluation.html @@ -1,11 +1,11 @@ -orm_functions/evaluation | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/evaluation

    Index

    Functions

    • checkIfFinalEvaluationExists(jobApplicationId: number): Promise<null | { evaluation_id: number }>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_general_purpose.html b/backend/docs/modules/orm_functions_general_purpose.html index db97090c..07a78681 100644 --- a/backend/docs/modules/orm_functions_general_purpose.html +++ b/backend/docs/modules/orm_functions_general_purpose.html @@ -1,2 +1,2 @@ -orm_functions/general_purpose | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/general_purpose

    Generated using TypeDoc

    \ No newline at end of file +orm_functions/general_purpose | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/general_purpose

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_job_application.html b/backend/docs/modules/orm_functions_job_application.html index 72a5852c..6f612960 100644 --- a/backend/docs/modules/orm_functions_job_application.html +++ b/backend/docs/modules/orm_functions_job_application.html @@ -1,17 +1,19 @@ -orm_functions/job_application | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/job_application

    Index

    Functions

    • changeEmailStatusOfJobApplication(jobApplicationId: number, emailStatus: email_status_enum): Promise<job_application>
    • getEvaluationsByYearForStudent(studentId: number, year: number): Promise<null | { evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; person: person; person_id: number }; motivation: null | string }[] }>
    • Parameters

      • studentId: number
      • year: number

      Returns Promise<null | { evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; person: person; person_id: number }; motivation: null | string }[] }>

      all the job applications associated with the given year

      +
    • getJobApplication(jobApplicationId: number): Promise<null | (job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[]; osoc: osoc })>
    • Parameters

      • jobApplicationId: number

      Returns Promise<null | (job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[]; osoc: osoc })>

      the found job application

      +
    • getJobApplicationByYear(year: number): Promise<(job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[] })[]>
    • Parameters

      • year: number

      Returns Promise<(job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[] })[]>

      all the job applications associated with the given year

      +
    • getJobApplicationByYearForStudent(studentId: number, year: number): Promise<job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[] }>
    • Parameters

      • studentId: number
      • year: number

      Returns Promise<job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[] }>

      all the job applications associated with the given year

      +
    • getLatestApplicationRolesForStudent(studentId: number): Promise<null | { applied_role: { role_id: number }[] }>
    • Parameters

      • studentId: number

      Returns Promise<null | { applied_role: { role_id: number }[] }>

      the list of selected roles in the application (if it exists)

      +
    • getLatestJobApplicationOfStudent(studentId: number): Promise<null | (job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[]; osoc: osoc })>
    • Parameters

      • studentId: number

      Returns Promise<null | (job_application & { applied_role: applied_role[]; attachment: attachment[]; job_application_skill: job_application_skill[]; osoc: osoc })>

      the found job applications of the given student

      +
    • getStudentEvaluationsFinal(studentId: number): Promise<{ evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { login_user_id: number; person: { email: null | string; github: null | string; name: string; person_id: number } }; motivation: null | string }[]; osoc: { year: number } }[]>
    • Parameters

      • studentId: number

      Returns Promise<{ evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { login_user_id: number; person: { email: null | string; github: null | string; name: string; person_id: number } }; motivation: null | string }[]; osoc: { year: number } }[]>

      al the evaluations associated with this student together with the osoc year

      +
    • getStudentEvaluationsTemp(studentId: number): Promise<{ evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { login_user_id: number; person: { email: null | string; github: null | string; name: string; person_id: number } }; motivation: null | string }[]; osoc: { year: number } }[]>
    • Parameters

      • studentId: number

      Returns Promise<{ evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { login_user_id: number; person: { email: null | string; github: null | string; name: string; person_id: number } }; motivation: null | string }[]; osoc: { year: number } }[]>

      al the evaluations associated with this student together with the osoc year

      +
    • getStudentEvaluationsTotal(studentId: number): Promise<{ evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { login_user_id: number; person: { email: null | string; github: null | string; name: string; person_id: number } }; motivation: null | string }[]; osoc: { year: number } }[]>
    • Parameters

      • studentId: number

      Returns Promise<{ evaluation: { decision: decision_enum; evaluation_id: number; is_final: boolean; login_user: null | { login_user_id: number; person: { email: null | string; github: null | string; name: string; person_id: number } }; motivation: null | string }[]; osoc: { year: number } }[]>

      al the evaluations associated with this student together with the osoc year

      +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_job_application_skill.html b/backend/docs/modules/orm_functions_job_application_skill.html index 142797a4..aeac6beb 100644 --- a/backend/docs/modules/orm_functions_job_application_skill.html +++ b/backend/docs/modules/orm_functions_job_application_skill.html @@ -1,11 +1,11 @@ -orm_functions/job_application_skill | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/job_application_skill

    Index

    Functions

    • deleteJobApplicationSkill(jobApplicationSkillId: number): Promise<job_application_skill & { job_application: job_application }>
    • getAllJobApplicationSkill(): Promise<job_application_skill[]>
    • getAllJobApplicationSkillByJobApplication(jobApplicationId: number): Promise<job_application_skill[]>
    • getJobApplicationSkill(jobApplicationSkillId: number): Promise<null | job_application_skill>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_language.html b/backend/docs/modules/orm_functions_language.html index 81478b44..f33a0990 100644 --- a/backend/docs/modules/orm_functions_language.html +++ b/backend/docs/modules/orm_functions_language.html @@ -1,9 +1,9 @@ -orm_functions/language | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/language

    Index

    Functions

    • createLanguage(name: string): Promise<language>
    • deleteLanguage(languageId: number): Promise<language>
    • deleteLanguageByName(name: string): Promise<language>
    • getAllLanguages(): Promise<language[]>
    • getLanguage(languageId: number): Promise<null | language>
    • returns:

      object with the name of the language

      +

      Parameters

      • languageId: number

      Returns Promise<null | language>

    • getLanguageByName(name: string): Promise<null | language>
    • returns:

      the language object with a matching name

      +

      Parameters

      • name: string

      Returns Promise<null | language>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_login_user.html b/backend/docs/modules/orm_functions_login_user.html index 2d77c2f9..433919f1 100644 --- a/backend/docs/modules/orm_functions_login_user.html +++ b/backend/docs/modules/orm_functions_login_user.html @@ -1,40 +1,44 @@ -orm_functions/login_user | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/login_user

    Index

    Functions

    • deleteLoginUserById(loginUserId: number): Promise<login_user & { person: person }>
    • getAllLoginUsers(): Promise<(login_user & { person: person })[]>
    • getLoginUserById(loginUserId: number): Promise<null | (login_user & { person: person })>
    • Parameters

      • loginUserId: number

      Returns Promise<null | (login_user & { person: person })>

      promise with the found data, or promise with null inside if no loginUser has the given id

      -
    • getPasswordLoginUser(loginUserId: number): Promise<null | { password: null | string }>
    • returns:

      password of the login user object

      -

      Parameters

      • loginUserId: number

      Returns Promise<null | { password: null | string }>

    • getPasswordLoginUserByPerson(personId: number): Promise<null | { password: null | string }>
    • returns:

      password of the login user object

      -

      Parameters

      • personId: number

      Returns Promise<null | { password: null | string }>

    • searchAllAdminAndCoachLoginUsers(bool: boolean): Promise<(login_user & { person: person })[]>
    • returns:

      all login user objects where the bool matches with both the admin and coach status

      -

      Parameters

      • bool: boolean

      Returns Promise<(login_user & { person: person })[]>

    • searchAllAdminLoginUsers(isAdmin: boolean): Promise<(login_user & { person: person })[]>
    • returns:

      all login user objects that match with the admin status

      -

      Parameters

      • isAdmin: boolean

      Returns Promise<(login_user & { person: person })[]>

    • searchAllCoachLoginUsers(isCoach: boolean): Promise<(login_user & { person: person })[]>
    • returns:

      all login user objects that match with the coach status

      -

      Parameters

      • isCoach: boolean

      Returns Promise<(login_user & { person: person })[]>

    • searchLoginUserByPerson(personId: number): Promise<null | (login_user & { person: person })>
    • returns:

      login user object

      -

      Parameters

      • personId: number

      Returns Promise<null | (login_user & { person: person })>

    • setAdmin(loginUserId: number, isAdmin: boolean): Promise<login_user & { person: person }>
    • getOsocYearsForLoginUser(loginUserId: number): Promise<number[]>
    • +

      get a list of years that should be visible for the login_user with given id

      +

      Parameters

      • loginUserId: number

      Returns Promise<number[]>

    • getPasswordLoginUser(loginUserId: number): Promise<null | { password: null | string }>
    • returns:

      password of the login user object

      +

      Parameters

      • loginUserId: number

      Returns Promise<null | { password: null | string }>

    • getPasswordLoginUserByPerson(personId: number): Promise<null | { password: null | string }>
    • returns:

      password of the login user object

      +

      Parameters

      • personId: number

      Returns Promise<null | { password: null | string }>

    • searchAllAdminAndCoachLoginUsers(bool: boolean): Promise<(login_user & { person: person })[]>
    • returns:

      all login user objects where the bool matches with both the admin and coach status

      +

      Parameters

      • bool: boolean

      Returns Promise<(login_user & { person: person })[]>

    • searchAllAdminLoginUsers(isAdmin: boolean): Promise<(login_user & { person: person })[]>
    • returns:

      all login user objects that match with the admin status

      +

      Parameters

      • isAdmin: boolean

      Returns Promise<(login_user & { person: person })[]>

    • searchAllCoachLoginUsers(isCoach: boolean): Promise<(login_user & { person: person })[]>
    • returns:

      all login user objects that match with the coach status

      +

      Parameters

      • isCoach: boolean

      Returns Promise<(login_user & { person: person })[]>

    • searchLoginUserByPerson(personId: number): Promise<null | (login_user & { person: person })>
    • returns:

      login user object

      +

      Parameters

      • personId: number

      Returns Promise<null | (login_user & { person: person })>

    • setAdmin(loginUserId: number, isAdmin: boolean): Promise<login_user & { person: person }>
    • Sets the is_admin field of the loginuser to IsAdmin

      Parameters

      • loginUserId: number

        the id of the loginUser whose field we are updating

      • isAdmin: boolean

        the new value of is_admin

      Returns Promise<login_user & { person: person }>

      a promise with the updated entry, the person object is also included

      -
    • setCoach(loginUserId: number, isCoach: boolean): Promise<login_user & { person: person }>
    • setCoach(loginUserId: number, isCoach: boolean): Promise<login_user & { person: person }>
    • Sets the is_coach field of the loginUser to isCoach

      Parameters

      • loginUserId: number
      • isCoach: boolean

      Returns Promise<login_user & { person: person }>

      a promise with the updated entry, the person object is also included

      -
    • updateLoginUser(loginUser: UpdateLoginUser): Promise<login_user & { person: person }>

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_login_user_osoc.html b/backend/docs/modules/orm_functions_login_user_osoc.html new file mode 100644 index 00000000..522ec569 --- /dev/null +++ b/backend/docs/modules/orm_functions_login_user_osoc.html @@ -0,0 +1,12 @@ +orm_functions/login_user_osoc | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/login_user_osoc

    Index

    Functions

    • addOsocToUser(loginUserId: number, osocId: number): Promise<undefined | login_user_osoc>
    • +

      creates an entry in the "in between table" for osoc and login_user. +An entry in this table indicates that this loginUser should be able to see the osoc edition

      +

      Parameters

      • loginUserId: number
      • osocId: number

      Returns Promise<undefined | login_user_osoc>

    • deleteOsocsForLoginuser(loginUserId: number): Promise<BatchPayload>
    • +

      Delete all connections between the osoc table and loginUser table for a given loginUser

      +

      Parameters

      • loginUserId: number

      Returns Promise<BatchPayload>

    • deleteOsocsLoginConnectionFromOsoc(osocId: number): Promise<BatchPayload>
    • +

      Delete all connections between the osoc table and loginUser table for a given osoc edition

      +

      Parameters

      • osocId: number

      Returns Promise<BatchPayload>

    • getLoginUserOsocByIds(loginUserId: number, osocId: number): Promise<null | login_user_osoc>
    • Parameters

      • loginUserId: number
      • osocId: number

      Returns Promise<null | login_user_osoc>

      null if an entry with these values exists, otherwise the entry

      +
    • getOsocYearsForLoginUserById(loginUserId: number): Promise<(login_user_osoc & { osoc: osoc })[]>
    • Parameters

      • loginUserId: number

      Returns Promise<(login_user_osoc & { osoc: osoc })[]>

      a promise with inside al list of objects with references to the osoc editions that are visible for the given loginUser

      +
    • removeOsocFromUser(loginUserId: number, osocId: number): Promise<undefined | BatchPayload>
    • +

      remove the permissions of an loginUser to see data from this osocEdition

      +

      Parameters

      • loginUserId: number
      • osocId: number

      Returns Promise<undefined | BatchPayload>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_orm_types.html b/backend/docs/modules/orm_functions_orm_types.html index 8971805f..96a6d981 100644 --- a/backend/docs/modules/orm_functions_orm_types.html +++ b/backend/docs/modules/orm_functions_orm_types.html @@ -1,11 +1,11 @@ -orm_functions/orm_types | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/orm_types

    Index

    Type aliases

    FilterBoolean: boolean | undefined
    +orm_functions/orm_types | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/orm_types

    Index

    Type aliases

    FilterBoolean: boolean | undefined

    type to use in a filter query for booleans

    -
    FilterNumber: number | undefined
    +
    FilterNumber: number | undefined

    type to use in a filter query for numbers

    -
    FilterNumberArray: number[] | undefined
    +
    FilterNumberArray: number[] | undefined

    type to use in a filter query for array of numbers

    -
    FilterSort: "asc" | "desc" | undefined
    +
    FilterSort: "asc" | "desc" | undefined

    type to use in a filter query for sorting

    -
    FilterString: string | undefined
    +
    FilterString: string | undefined

    type to use in a filter query for strings

    -
    FilterStringArray: string[] | undefined

    Legend

    • Variable
    • Function
    • Type alias
    • Interface

    Settings

    Theme

    Generated using TypeDoc

    \ No newline at end of file +
    FilterStringArray: string[] | undefined

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_osoc.html b/backend/docs/modules/orm_functions_osoc.html index c000cf77..ddd2dfc8 100644 --- a/backend/docs/modules/orm_functions_osoc.html +++ b/backend/docs/modules/orm_functions_osoc.html @@ -1,19 +1,22 @@ -orm_functions/osoc | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/osoc

    Index

    Functions

    • createOsoc(year: number): Promise<osoc>
    • deleteOsoc(osocId: number): Promise<osoc>
    • getAllOsoc(): Promise<(osoc & { _count: { project: number } })[]>
    • Returns Promise<(osoc & { _count: { project: number } })[]>

      a list of all the osoc objects in the database

      +
    • getLatestOsoc(): Promise<null | osoc>
    • getNewestOsoc(): Promise<null | osoc>
    • getOsocAfterYear(year: number): Promise<osoc[]>
    • returns:

      all the osoc objects that took place after the supplied year

      +

      Parameters

      • year: number

      Returns Promise<osoc[]>

    • getOsocBeforeYear(year: number): Promise<osoc[]>
    • returns:

      all the osoc objects that took place before the supplied year

      +

      Parameters

      • year: number

      Returns Promise<osoc[]>

    • getOsocById(osocId: number): Promise<null | osoc>
    • Parameters

      • osocId: number

      Returns Promise<null | osoc>

      the found osoc edition in a promise

      +
    • getOsocByYear(year: number): Promise<null | osoc>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_password_reset.html b/backend/docs/modules/orm_functions_password_reset.html index 8b94ae32..f593e6b8 100644 --- a/backend/docs/modules/orm_functions_password_reset.html +++ b/backend/docs/modules/orm_functions_password_reset.html @@ -1,4 +1,4 @@ -orm_functions/password_reset | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/password_reset

    Index

    Functions

    • createOrUpdateReset(loginUserId: number, resetId: string, validUntil: Date): Promise<password_reset>
    • findResetByCode(resetCode: string): Promise<null | password_reset>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_person.html b/backend/docs/modules/orm_functions_person.html index e876663e..767155c7 100644 --- a/backend/docs/modules/orm_functions_person.html +++ b/backend/docs/modules/orm_functions_person.html @@ -1,11 +1,15 @@ -orm_functions/person | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/person

    Index

    Functions

    • deletePersonById(personId: number): Promise<person>
    • searchPersonByName(name: string): Promise<person[]>
    • returns:

      a list of all the person objects in the database that match

      +

      Parameters

      • name: string

      Returns Promise<person[]>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_project.html b/backend/docs/modules/orm_functions_project.html index 316d652e..16b6b5c2 100644 --- a/backend/docs/modules/orm_functions_project.html +++ b/backend/docs/modules/orm_functions_project.html @@ -1,40 +1,43 @@ -orm_functions/project | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/project

    Index

    Functions

    • deleteProject(projectId: number): Promise<project>
    • getAllProjects(): Promise<project[]>
    • getProjectById(projectId: number): Promise<null | (project & { osoc: osoc })>
    • returns:

      object with all the info about this project

      +

      Parameters

      • projectId: number

      Returns Promise<null | (project & { osoc: osoc })>

    • getProjectByName(projectName: string): Promise<project[]>
    • returns:

      object with all the info about this project

      +

      Parameters

      • projectName: string

      Returns Promise<project[]>

    • getProjectYear(projectId: number): Promise<number>
    • getProjectsByEndDate(endDate: Date): Promise<project[]>
    • Parameters

      • endDate: Date

      Returns Promise<project[]>

      all the projects with a matching end date in the database

      +
    • getProjectsByOsocEdition(osocId: number): Promise<project[]>
    • getProjectsByPartner(partner: string): Promise<project[]>
    • getProjectsByStartDate(startDate: Date): Promise<project[]>
    • Parameters

      • startDate: Date

      Returns Promise<project[]>

      all the projects with a matching start date in the database

      +
    • getProjectsEndedAfterDate(date: Date): Promise<project[]>
    • getProjectsEndedBeforeDate(date: Date): Promise<project[]>
    • getProjectsStartedAfterDate(date: Date): Promise<project[]>
    • Parameters

      • date: Date

      Returns Promise<project[]>

      all the projects that started after the supplied date

      +
    • getProjectsStartedBeforeDate(date: Date): Promise<project[]>
    • Parameters

      • date: Date

      Returns Promise<project[]>

      all the projects that started before the supplied date

      +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_project_role.html b/backend/docs/modules/orm_functions_project_role.html index 225b95f8..89da4775 100644 --- a/backend/docs/modules/orm_functions_project_role.html +++ b/backend/docs/modules/orm_functions_project_role.html @@ -1,12 +1,12 @@ -orm_functions/project_role | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/project_role

    Index

    Functions

    • deleteProjectRole(projectRoleId: number): Promise<project_role>
    • getProjectRolesByProject(projectId: number): Promise<project_role[]>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_project_user.html b/backend/docs/modules/orm_functions_project_user.html index 60e3d087..887ffa08 100644 --- a/backend/docs/modules/orm_functions_project_user.html +++ b/backend/docs/modules/orm_functions_project_user.html @@ -1,5 +1,6 @@ -orm_functions/project_user | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/project_user

    Index

    Functions

    • getUsersFor(project: number): Promise<{ login_user: { is_admin: boolean; is_coach: boolean; login_user_id: number; person: person } }[]>

    Returns Promise<{ login_user: { is_admin: boolean; is_coach: boolean; login_user_id: number; person: person }; project_user_id: number }[]>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_role.html b/backend/docs/modules/orm_functions_role.html index 0d964ade..7eba1d6f 100644 --- a/backend/docs/modules/orm_functions_role.html +++ b/backend/docs/modules/orm_functions_role.html @@ -1,14 +1,14 @@ -orm_functions/role | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/role

    Index

    Functions

    • createRole(name: string): Promise<role>
    • deleteRole(roleId: number): Promise<role>
    • getRole(roleId: number): Promise<null | role>
    • returns:

      object with the name of the role

      +

      Parameters

      • roleId: number

      Returns Promise<null | role>

    • getRolesByName(name: string): Promise<null | role>
    • returns:

      all the role objects with a matching name

      +

      Parameters

      • name: string

      Returns Promise<null | role>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_session_key.html b/backend/docs/modules/orm_functions_session_key.html index f9755316..ab1c80f5 100644 --- a/backend/docs/modules/orm_functions_session_key.html +++ b/backend/docs/modules/orm_functions_session_key.html @@ -1,20 +1,20 @@ -orm_functions/session_key | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/session_key

    Index

    Functions

    • addSessionKey(loginUserId: number, key: string, date: Date): Promise<session_keys>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_student.html b/backend/docs/modules/orm_functions_student.html index e7e43deb..d7833ff9 100644 --- a/backend/docs/modules/orm_functions_student.html +++ b/backend/docs/modules/orm_functions_student.html @@ -1,10 +1,12 @@ -orm_functions/student | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/student

    Index

    Functions

    • deleteStudent(studentId: number): Promise<student & { person: person }>
    • getAllStudents(): Promise<(student & { person: person })[]>
    • Returns Promise<(student & { person: person })[]>

      a list of all the student objects in the database together with their personal info

      +
    • getAppliedYearsForStudent(studentId: number): Promise<number[]>
    • Parameters

      • studentId: number

      Returns Promise<number[]>

      a list of all the years the student has applied for

      +
    • getStudent(studentId: number): Promise<null | (student & { person: person })>
    • returns:

      object with all the info about this student together with their personal info

      +

      Parameters

      • studentId: number

      Returns Promise<null | (student & { person: person })>

    • searchStudentByGender(gender: string): Promise<(student & { person: person })[]>
    • returns:

      a list of all the person objects in the database that match

      +

      Parameters

      • gender: string

      Returns Promise<(student & { person: person })[]>

    • updateStudent(student: UpdateStudent): Promise<student & { person: person }>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/orm_functions_template.html b/backend/docs/modules/orm_functions_template.html index 4ab497cc..042a4028 100644 --- a/backend/docs/modules/orm_functions_template.html +++ b/backend/docs/modules/orm_functions_template.html @@ -1 +1 @@ -orm_functions/template | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/template

    Index

    Functions

    • deleteTemplate(id: number): Promise<template_email>
    • getAllTemplates(): Promise<template_email[]>
    • getTemplateById(templateId: number): Promise<null | template_email>
    • getTemplatesByName(name: string): Promise<(template_email & { login_user: login_user })[]>

    Generated using TypeDoc

    \ No newline at end of file +orm_functions/template | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module orm_functions/template

    Index

    Functions

    • deleteTemplate(id: number): Promise<template_email>
    • getAllTemplates(): Promise<template_email[]>
    • getTemplateById(templateId: number): Promise<null | template_email>
    • getTemplatesByName(name: string): Promise<(template_email & { login_user: null | login_user })[]>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_admin.html b/backend/docs/modules/routes_admin.html index e9d2608e..06fab48a 100644 --- a/backend/docs/modules/routes_admin.html +++ b/backend/docs/modules/routes_admin.html @@ -1,23 +1,23 @@ -routes/admin | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/admin

    Index

    Functions

    • deleteAdmin(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_coach.html b/backend/docs/modules/routes_coach.html index dd24e858..dbe754dc 100644 --- a/backend/docs/modules/routes_coach.html +++ b/backend/docs/modules/routes_coach.html @@ -1,29 +1,23 @@ -routes/coach | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/coach

    Index

    Functions

    • deleteCoach(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_followup.html b/backend/docs/modules/routes_followup.html index ee13f54a..3c0906ac 100644 --- a/backend/docs/modules/routes_followup.html +++ b/backend/docs/modules/routes_followup.html @@ -1,19 +1,13 @@ -routes/followup | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/followup

    Index

    Functions

    • getFollowup(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.SingleFollowup>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_form.html b/backend/docs/modules/routes_form.html index 777c29aa..d320a3c5 100644 --- a/backend/docs/modules/routes_form.html +++ b/backend/docs/modules/routes_form.html @@ -1,4 +1,4 @@ -routes/form | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/form

    Index

    Functions

    • addAttachmentsToDatabase(formResponse: FormAttachment, job_applicationId: Id): Promise<Responses.Empty>
    • +routes/form | backend
      Options
      All
      • Public
      • Public/Protected
      • All
      Menu

      Module routes/form

      Index

      Functions

      • addAttachmentsToDatabase(formResponse: FormAttachment, job_applicationId: Id): Promise<Responses.Empty>
      • Attempts to add attachments to the database.

        Parameters

        • formResponse: FormAttachment

          The response with the data.

          @@ -6,7 +6,7 @@

          The job_application id object.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • addJobApplicationToDatabase(formResponse: FormJobApplication, student_id: Id): Promise<Responses.Id>
      • addJobApplicationToDatabase(formResponse: FormJobApplication, student_id: Id): Promise<Responses.Id>
      • Attempts to add a job application to the database.

        Parameters

        • formResponse: FormJobApplication

          The response with the data.

          @@ -14,13 +14,13 @@

          The student id object.

        Returns Promise<Responses.Id>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • addPersonToDatabase(formResponse: FormPerson): Promise<Responses.Id>
      • addPersonToDatabase(formResponse: FormPerson): Promise<Responses.Id>
      • Attempts to add a person to the database.

        Parameters

        • formResponse: FormPerson

          The response with the data.

        Returns Promise<Responses.Id>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • addRolesToDatabase(formResponse: FormRoles, job_applicationId: Id): Promise<Responses.Empty>
      • addRolesToDatabase(formResponse: FormRoles, job_applicationId: Id): Promise<Responses.Empty>
      • Attempts to add roles to the database.

        Parameters

        • formResponse: FormRoles

          The response with the data.

          @@ -28,7 +28,7 @@

          The job_application id object.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • addSkillsToDatabase(formResponse: FormJobApplicationSkill, job_applicationId: Id): Promise<Responses.Empty>
      • addSkillsToDatabase(formResponse: FormJobApplicationSkill, job_applicationId: Id): Promise<Responses.Empty>
      • Attempts to add a job application skill to the database.

        Parameters

        • formResponse: FormJobApplicationSkill

          The response with the data.

          @@ -36,7 +36,7 @@

          The job application id.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • addStudentToDatabase(formResponse: FormStudent, personId: Id): Promise<Responses.Id_alumni>
      • addStudentToDatabase(formResponse: FormStudent, personId: Id): Promise<Responses.Id_alumni>
      • Attempts to add a student to the database.

        Parameters

        • formResponse: FormStudent

          The response with the data.

          @@ -44,174 +44,174 @@

          The id of a person.

        Returns Promise<Responses.Id_alumni>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • checkQuestionsExist(questions: FormResponse<Question>[]): boolean
      • Parameters

        • questions: FormResponse<Question>[]

        Returns boolean

      • checkWordInAnswer(question: Question, word: string): Responses.FormResponse<boolean>
      • checkQuestionsExist(questions: FormResponse<Question>[]): boolean
      • Parameters

        • questions: FormResponse<Question>[]

        Returns boolean

      • checkWordInAnswer(question: Question, word: string): Responses.FormResponse<boolean>
      • This function checks if the answer on a certain question contains a word.

        Parameters

        • question: Question

          The question.

        • word: string

          the word we are searching for in the answer.

        Returns Responses.FormResponse<boolean>

        True if the question options contain the word, else false.

        -
      • createForm(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • createForm(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • Attempts to create a new form in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • filterChosenOption(question: Question): Responses.FormResponse<Requests.Option>
      • filterChosenOption(question: Question): Responses.FormResponse<Requests.Option>
      • This function searches the chosen option for a given question.

        Parameters

        • question: Question

          The question.

        Returns Responses.FormResponse<Requests.Option>

        The option that corresponds with the given answer.

        -
      • filterQuestion(form: Form, key: string): Responses.FormResponse<Requests.Question>
      • filterQuestion(form: Form, key: string): Responses.FormResponse<Requests.Question>
      • This function searches a question with a given key in the form.

        Parameters

        • form: Form

          The form with the answers.

        • key: string

          The key of the question.

        Returns Responses.FormResponse<Requests.Question>

        The question that corresponds with the given key.

        -
      • getAlumni(form: Form): Promise<boolean>
      • getAlumni(form: Form): Promise<boolean>
      • Parse the form to the email of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<boolean>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getAppliedRoles(form: Form): Promise<string[]>
      • getAppliedRoles(form: Form): Promise<string[]>
      • Parse the form to the roles of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string[]>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getBestSkill(form: Form): Promise<string>
      • getBestSkill(form: Form): Promise<string>
      • Parse the form to the best skill this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getBirthName(form: Form): Promise<string>
      • getBirthName(form: Form): Promise<string>
      • Parse the form to the birth name of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getCV(form: Form): Promise<Responses.FormAttachmentResponse>
      • getCV(form: Form): Promise<Responses.FormAttachmentResponse>
      • Parse the form to the cv of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormAttachmentResponse>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getEducationDuration(form: Form): Promise<number | null>
      • getEducationDuration(form: Form): Promise<number | null>
      • Parse the form to the duration of the education of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<number | null>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getEducationLevel(form: Form): Promise<string>
      • getEducationLevel(form: Form): Promise<string>
      • Parse the form to the education levels of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getEducationUniversity(form: Form): Promise<string | null>
      • getEducationUniversity(form: Form): Promise<string | null>
      • Parse the form to the university of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string | null>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getEducationYear(form: Form): Promise<string | null>
      • getEducationYear(form: Form): Promise<string | null>
      • Parse the form to the current year of the education of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string | null>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getEducations(form: Form): Promise<string[]>
      • getEducations(form: Form): Promise<string[]>
      • Parse the form to the educations of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string[]>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getEmail(form: Form): Promise<string>
      • getEmail(form: Form): Promise<string>
      • Parse the form to the email of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getEnglishLevel(form: Form): Promise<number>
      • getEnglishLevel(form: Form): Promise<number>
      • Parse the form to the english level of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<number>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getFunFact(form: Form): Promise<string>
      • getFunFact(form: Form): Promise<string>
      • Parse the form to the fun fact of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getGender(form: Form): Promise<string>
      • getGender(form: Form): Promise<string>
      • Parse the form to the gender of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getLastName(form: Form): Promise<string>
      • getLastName(form: Form): Promise<string>
      • Parse the form to the last name of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getMostFluentLanguage(form: Form): Promise<string>
      • getMostFluentLanguage(form: Form): Promise<string>
      • Parse the form to the most fluent language of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getMotivation(form: Form): Promise<Responses.FormAttachmentResponse>
      • getMotivation(form: Form): Promise<Responses.FormAttachmentResponse>
      • Parse the form to the motivation of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormAttachmentResponse>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getNickname(form: Form): Promise<string | null>
      • getNickname(form: Form): Promise<string | null>
      • Parse the form to the email of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string | null>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getPhoneNumber(form: Form): Promise<string>
      • getPhoneNumber(form: Form): Promise<string>
      • Parse the form to the phone number of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getPortfolio(form: Form): Promise<Responses.FormAttachmentResponse>
      • getPortfolio(form: Form): Promise<Responses.FormAttachmentResponse>
      • Parse the form to the portfolio of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormAttachmentResponse>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getPronouns(form: Form): Promise<string | null>
      • getPronouns(form: Form): Promise<string | null>
      • Parse the form to the pronouns of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string | null>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getResponsibilities(form: Form): Promise<string | null>
      • getResponsibilities(form: Form): Promise<string | null>
      • Parse the form to the responsibilities of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string | null>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getRouter(): express.Router
      • getRouter(): express.Router
      • Gets the router for all /form/ related endpoints.

        Returns express.Router

        An Express.js {@link express.Router} routing all /form/ endpoints.

        -
      • getVolunteerInfo(form: Form): Promise<string>
      • getVolunteerInfo(form: Form): Promise<string>
      • Parse the form to the volunteer info of this student.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<string>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • isStudentCoach(form: Form, hasAlreadyParticipated: boolean): Promise<boolean | null>
      • isStudentCoach(form: Form, hasAlreadyParticipated: boolean): Promise<boolean | null>
      • Parse the form to the choice of being a student coach.

        Parameters

        • form: Form

          The form with the answers.

          @@ -219,13 +219,13 @@

          true if the student from the job application has already taken part in osoc previous years

        Returns Promise<boolean | null>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • jsonToAttachments(form: Form): Promise<Responses.FormAttachment>
      • jsonToAttachments(form: Form): Promise<Responses.FormAttachment>
      • Attempts to parse the answers in the form into attachment entities.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormAttachment>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • jsonToJobApplication(form: Form, hasAlreadyTakenPart: boolean): Promise<Responses.FormJobApplication>
      • jsonToJobApplication(form: Form, hasAlreadyTakenPart: boolean): Promise<Responses.FormJobApplication>
      • Attempts to parse the answers in the form into a job application entity.

        Parameters

        • form: Form

          The form with the answers.

          @@ -233,28 +233,28 @@

          true if the student has already taken part in osoc in a prev edition

        Returns Promise<Responses.FormJobApplication>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • jsonToPerson(form: Form): Promise<Responses.FormPerson>
      • jsonToPerson(form: Form): Promise<Responses.FormPerson>
      • Attempts to parse the answers in the form into a person entity.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormPerson>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • jsonToRoles(form: Form): Promise<Responses.FormRoles>
      • jsonToRoles(form: Form): Promise<Responses.FormRoles>
      • Attempts to parse the answers in the form into role entities.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormRoles>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • jsonToSkills(form: Form): Promise<Responses.FormJobApplicationSkill>
      • jsonToSkills(form: Form): Promise<Responses.FormJobApplicationSkill>
      • Attempts to parse the answers in the form into job application skills entities.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormJobApplicationSkill>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • jsonToStudent(form: Form): Promise<Responses.FormStudent>
      • jsonToStudent(form: Form): Promise<Responses.FormStudent>
      • Attempts to parse the answers in the form into a student entity.

        Parameters

        • form: Form

          The form with the answers.

        Returns Promise<Responses.FormStudent>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -

      Legend

      • Variable
      • Function
      • Type alias
      • Interface

      Settings

      Theme

      Generated using TypeDoc

      \ No newline at end of file +
    • readFile(directoryPart: null | string, file: string): Promise<T.Requests.Form>
    • Parameters

      • directoryPart: null | string
      • file: string

      Returns Promise<T.Requests.Form>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_form_keys_json.html b/backend/docs/modules/routes_form_keys_json.html deleted file mode 100644 index 60126343..00000000 --- a/backend/docs/modules/routes_form_keys_json.html +++ /dev/null @@ -1 +0,0 @@ -routes/form_keys.json | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/form_keys.json

    Index

    Properties

    Properties

    export=: { addPronouns: string; alumni: string; appliedRole: string; appliedRoleInput: string; bestSkill: string; birthName: string; cvLink: string; cvUpload: string; eduDuration: string; eduInstitute: string; eduLevel: string; eduLevelInput: string; eduYear: string; edus: string; edusInput: string; emailAddress: string; englishLevel: string; funFact: string; gender: string; lastName: string; liveInBelgium: string; mostFluentLanguage: string; mostFluentLanguageInput: string; motivationInput: string; motivationLink: string; motivationUpload: string; nickname: string; nicknameInput: string; phoneNumber: string; portfolioLink: string; portfolioUpload: string; preferredPronouns: string; pronounsInput: string; responsibilities: string; studentCoach: string; volunteerInfo: string; workInJuly: string }

    Type declaration

    • addPronouns: string
    • alumni: string
    • appliedRole: string
    • appliedRoleInput: string
    • bestSkill: string
    • birthName: string
    • cvLink: string
    • cvUpload: string
    • eduDuration: string
    • eduInstitute: string
    • eduLevel: string
    • eduLevelInput: string
    • eduYear: string
    • edus: string
    • edusInput: string
    • emailAddress: string
    • englishLevel: string
    • funFact: string
    • gender: string
    • lastName: string
    • liveInBelgium: string
    • mostFluentLanguage: string
    • mostFluentLanguageInput: string
    • motivationInput: string
    • motivationLink: string
    • motivationUpload: string
    • nickname: string
    • nicknameInput: string
    • phoneNumber: string
    • portfolioLink: string
    • portfolioUpload: string
    • preferredPronouns: string
    • pronounsInput: string
    • responsibilities: string
    • studentCoach: string
    • volunteerInfo: string
    • workInJuly: string

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_github.html b/backend/docs/modules/routes_github.html index 97b87f3c..4e2bb5fa 100644 --- a/backend/docs/modules/routes_github.html +++ b/backend/docs/modules/routes_github.html @@ -1,33 +1,33 @@ -routes/github | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/github

    Index

    Variables

    states: string[] = []

    Functions

    • checkState(state: string): boolean
    • genState(redirect: string): string
    • Generates a new state for GitHub, then adds it to the current states. This state is a a string of 64 cryptographically random bytes.

      -

      Returns string

      The new state.

      -
    • getHome(): string
    • getHome(): string
    • Gets the home URL for the github callback.

      Returns string

      The home URL.

      -
    • getRouter(): express.Router
    • ghExchangeAccessToken(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>): Promise<void>
    • getRouter(): express.Router
    • ghExchangeAccessToken(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>): Promise<void>
    • Step two of the GitHub OAuth process: exchanging the temporary code for an access token. This function first asks an access token, then checks if a a user exists in our system and if not, creates one.

      -

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
      • res: Response<any, Record<string, any>>

      Returns Promise<void>

    • ghIdentity(resp: Response<any, Record<string, any>>): Promise<void>
    • +

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
      • res: Response<any, Record<string, any>>

      Returns Promise<void>

    • ghIdentity(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, resp: Response<any, Record<string, any>>): Promise<void>
    • Step one of the GitHub OAuth process: getting the identity of the user. This calls GitHub's login, then asks Github to redirect the user to /github/challenge on our server. This function only generates a new state, makes it valid and then redirects.

      -

      Parameters

      • resp: Response<any, Record<string, any>>

      Returns Promise<void>

    • ghSignupOrLogin(login: GHLogin): Promise<Responses.Login>
    • +

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
      • resp: Response<any, Record<string, any>>

      Returns Promise<void>

    • ghSignupOrLogin(login: GHLogin): Promise<Responses.GithubLogin>
    • Callback for the actual signup and/or login. Uses the provided GitHub data to access our underlying database. If the user doesn't exist, their account is created. If the user exists, we check if we need to update their name and/or GitHub handle.

      -

      Parameters

      • login: GHLogin

      Returns Promise<Responses.Login>

    • githubNameChange(login: GHLogin, person: { firstname: string; github: null | string; login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; password: null | string }; person_id: number }): boolean
    • githubNameChange(login: GHLogin, person: { github: null | string; login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; password: null | string }; name: string; person_id: number }): boolean
    • Checks if we need to update a GitHub user's name and/or handle.

      -

      Parameters

      • login: GHLogin
      • person: { firstname: string; github: null | string; login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; password: null | string }; person_id: number }
        • firstname: string
        • github: null | string
        • login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; password: null | string }
        • person_id: number

      Returns boolean

    • parseGHLogin(data: Anything): Promise<Requests.GHLogin>
    • +

      Parameters

      • login: GHLogin
      • person: { github: null | string; login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; password: null | string }; name: string; person_id: number }
        • github: null | string
        • login_user: null | { account_status: account_status_enum; is_admin: boolean; is_coach: boolean; login_user_id: number; password: null | string }
        • name: string
        • person_id: number

      Returns boolean

    • parseGHLogin(data: Anything): Promise<Requests.GHLogin>
    • Checks if all required fields are available. We need (at least) a login, name and id in the request.

      -

      Parameters

      • data: Anything

      Returns Promise<Requests.GHLogin>

    Generated using TypeDoc

    \ No newline at end of file +

    Parameters

    Returns Promise<Requests.GHLogin>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_login.html b/backend/docs/modules/routes_login.html index 03d556e8..9d884c87 100644 --- a/backend/docs/modules/routes_login.html +++ b/backend/docs/modules/routes_login.html @@ -1,17 +1,17 @@ -routes/login | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/login

    Index

    Functions

    • getRouter(): express.Router

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_osoc.html b/backend/docs/modules/routes_osoc.html new file mode 100644 index 00000000..a0cf1d3d --- /dev/null +++ b/backend/docs/modules/routes_osoc.html @@ -0,0 +1,27 @@ +routes/osoc | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/osoc

    Index

    Functions

    • createOsocEdition(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.OsocEdition>
    • +

      Attempts to create a new project in the system.

      +

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
        +

        The Express.js request to extract all required data from.

        +

      Returns Promise<Responses.OsocEdition>

      See the API documentation. Successes are passed using +Promise.resolve, failures using Promise.reject.

      +
    • deleteOsocEditionRequest(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
        +

        The Express.js request to extract all required data from.

        +

      Returns Promise<Responses.Empty>

      See the API documentation. Successes are passed using +Promise.resolve, failures using Promise.reject.

      +
    • filterYear(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.OsocEditionList>
    • +

      Attempts to filter osoc editions in the system by year.

      +

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
        +

        The Express.js request to extract all required data from.

        +

      Returns Promise<Responses.OsocEditionList>

      See the API documentation. Successes are passed using +Promise.resolve, failures using Promise.reject.

      +
    • getRouter(): express.Router
    • +

      Gets the router for all /osoc/ related endpoints.

      +

      Returns express.Router

      An Express.js {@link express.Router} routing all /osoc/ +endpoints.

      +
    • listOsocEditions(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.OsocEditionList>
    • +

      Attempts to list all osoc editions in the system.

      +

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
        +

        The Express.js request to extract all required data from.

        +

      Returns Promise<Responses.OsocEditionList>

      See the API documentation. Successes are passed using +Promise.resolve, failures using Promise.reject.

      +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_project.html b/backend/docs/modules/routes_project.html index b608747a..adce4bb2 100644 --- a/backend/docs/modules/routes_project.html +++ b/backend/docs/modules/routes_project.html @@ -1,41 +1,41 @@ -routes/project | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/project

    Index

    Functions

    • createProject(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Project>
    • +routes/project | backend
      Options
      All
      • Public
      • Public/Protected
      • All
      Menu

      Module routes/project

      Index

      Functions

      • assignCoach(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectUser>
      • Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

        Returns Promise<Responses.ProjectUser>

      • assignStudent(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ModProjectStudent>
      • Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

        Returns Promise<Responses.ModProjectStudent>

      • createProject(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Project>
      • Attempts to create a new project in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Project>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • createProjectRoleFor(project: number, role: string): Promise<{ count: number; role: number }>
      • Parameters

        • project: number
        • role: string

        Returns Promise<{ count: number; role: number }>

      • deleteProject(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • createProjectRoleFor(project: number, role: string): Promise<{ count: number; project_role_id: number }>
      • Parameters

        • project: number
        • role: string

        Returns Promise<{ count: number; project_role_id: number }>

      • deleteProject(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • Attempts to delete a project from the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • filterProjects(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectFilterList>
      • filterProjects(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectListAndContracts>
      • Attempts to filter projects in the system by name, client, coaches or fully assigned.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

          -

        Returns Promise<Responses.ProjectFilterList>

        See the API documentation. Successes are passed using +

    Returns Promise<Responses.ProjectListAndContracts>

    See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

    -
    • getDraftedStudents(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectDraftedStudents>
    • getDraftedStudents(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectDraftedStudents>
    • Attempts to get all drafted students in the system for a project.

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

        The Express.js request to extract all required data from.

      Returns Promise<Responses.ProjectDraftedStudents>

      See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

      -
    • getFreeSpotsFor(role: string, project: number): Promise<{ count: number; role: number }>
    • Parameters

      • role: string
      • project: number

      Returns Promise<{ count: number; role: number }>

    • getProject(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Project>
    • getFreeSpotsFor(role: string, project: number): Promise<{ count: number; project_role_id: number; role_id: number }>
    • Parameters

      • role: string
      • project: number

      Returns Promise<{ count: number; project_role_id: number; role_id: number }>

    • getProject(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectAndContracts>
    • Attempts to get all data for a certain project in the system.

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

        The Express.js request to extract all required data from.

        -

      Returns Promise<Responses.Project>

      See the API documentation. Successes are passed using +

    Returns Promise<Responses.ProjectAndContracts>

    See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

    -
    • getProjectConflicts(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ConflictList>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.ConflictList>

    • getRouter(): express.Router
    • getRouter(): express.Router
    • Gets the router for all /coaches/ related endpoints.

      Returns express.Router

      An Express.js {@link express.Router} routing all /coaches/ endpoints.

      -
    • listProjects(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectList>
    • listProjects(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ProjectListAndContracts>
    • Attempts to list all projects in the system.

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

        The Express.js request to extract all required data from.

        -

      Returns Promise<Responses.ProjectList>

      See the API documentation. Successes are passed using +

    Returns Promise<Responses.ProjectListAndContracts>

    See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

    -
    • modProject(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Project>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Project>

    • modProjectStudent(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.ModProjectStudent>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.ModProjectStudent>

    • unAssignStudent(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Empty>

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_reset.html b/backend/docs/modules/routes_reset.html index a88b4621..14fe46c7 100644 --- a/backend/docs/modules/routes_reset.html +++ b/backend/docs/modules/routes_reset.html @@ -1,20 +1,20 @@ -routes/reset | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/reset

    Index

    Functions

    • checkCode(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
    • +routes/reset | backend
      Options
      All
      • Public
      • Public/Protected
      • All
      Menu

      Module routes/reset

      Index

      Functions

      • checkCode(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • Route used to check if a reset code is valid. Use route /reset/:id with a 'GET' request.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
          -

        Returns Promise<Responses.Empty>

      • createEmail(resetID: string): string

      Returns Promise<Responses.Empty>

    • createEmail(resetID: string): string
    • Returns the html body for the email with the reset code applied.

      Parameters

      • resetID: string

        The ID that validates the password reset.

        -

      Returns string

    • getRouter(): express.Router
    • requestReset(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>

    Returns string

    • getRouter(): express.Router
    • requestReset(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
    • Handles password reset requests If the email in the 'GET' body is correct, an email with a reset link will be sent. If not returns an error. Route: /reset

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

        Request body should be of form { email: string }

        -

      Returns Promise<Responses.Empty>

    • resetPassword(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Key>

    Returns Promise<Responses.Empty>

    • resetPassword(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Key>
    • Route that will reset the password when the code and password are valid. Use route /reset/:id with a 'POST' request with body of form { password: string }

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
        -

      Returns Promise<Responses.Key>

    • sendMail(mail: Email): Promise<SentMessageInfo>

    Generated using TypeDoc

    \ No newline at end of file +

    Returns Promise<Responses.Key>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_role.html b/backend/docs/modules/routes_role.html index 0fa4740f..696d3613 100644 --- a/backend/docs/modules/routes_role.html +++ b/backend/docs/modules/routes_role.html @@ -1,17 +1,17 @@ -routes/role | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/role

    Index

    Functions

    • createStudentRole(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.PartialStudent>
    • +routes/role | backend
      Options
      All
      • Public
      • Public/Protected
      • All
      Menu

      Module routes/role

      Index

      Functions

      • createStudentRole(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.PartialStudent>
      • Attempts to create a new role in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.PartialStudent>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getRouter(): express.Router
      • getRouter(): express.Router
      • Gets the router for all /role/ related endpoints.

        Returns express.Router

        An Express.js {@link express.Router} routing all /role/ endpoints.

        -
      • listStudentRoles(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.StudentList>
      • listStudentRoles(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.StudentRoles>
      • Attempts to list all roles in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

          -

        Returns Promise<Responses.StudentList>

        See the API documentation. Successes are passed using +

    Returns Promise<Responses.StudentRoles>

    See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

    -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_session_key_json.html b/backend/docs/modules/routes_session_key_json.html deleted file mode 100644 index a8e1a979..00000000 --- a/backend/docs/modules/routes_session_key_json.html +++ /dev/null @@ -1 +0,0 @@ -routes/session_key.json | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/session_key.json

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_student.html b/backend/docs/modules/routes_student.html index fda15e59..580f9607 100644 --- a/backend/docs/modules/routes_student.html +++ b/backend/docs/modules/routes_student.html @@ -1,47 +1,41 @@ -routes/student | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/student

    Index

    Functions

    • createStudentConfirmation(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
    • +routes/student | backend
      Options
      All
      • Public
      • Public/Protected
      • All
      Menu

      Module routes/student

      Index

      Functions

      • createStudentConfirmation(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • Attempts to create a student confirmation in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • createStudentSuggestion(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • createStudentSuggestion(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • Attempts to create a student suggestion in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • deleteStudent(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • deleteStudent(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • Attempts to delete a student from the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • filterStudents(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.StudentList>
      • filterStudents(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.StudentList>
      • Attempts to filter students in the system by name, role, alumni, student coach, status or email.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.StudentList>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getRouter(): express.Router
      • getRouter(): express.Router
      • Gets the router for all /student/ related endpoints.

        Returns express.Router

        An Express.js {@link express.Router} routing all /student/ endpoints.

        -
      • getStudent(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Student>
      • getStudent(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Student>
      • Attempts to get all data for a certain student in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Student>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getStudentSuggestions(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.SuggestionInfo>
      • getStudentSuggestions(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.AllStudentEvaluationsResponse>
      • Attempts to list all suggestions for a certain student.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

          -

        Returns Promise<Responses.SuggestionInfo>

        See the API documentation. Successes are passed using +

    Returns Promise<Responses.AllStudentEvaluationsResponse>

    See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

    -
    • listStudents(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.StudentList>
    • -

      Attempts to list all students in the system.

      -

      Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
        -

        The Express.js request to extract all required data from.

        -

      Returns Promise<Responses.StudentList>

      See the API documentation. Successes are passed using -Promise.resolve, failures using Promise.reject.

      -

    Generated using TypeDoc

    \ No newline at end of file +

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_template.html b/backend/docs/modules/routes_template.html index 82e62fc1..782c5454 100644 --- a/backend/docs/modules/routes_template.html +++ b/backend/docs/modules/routes_template.html @@ -1 +1 @@ -routes/template | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/template

    Index

    Functions

    • createTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Template>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Template>

    • deleteTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Empty>

    • getAllTemplates(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.TemplateList>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.TemplateList>

    • getRouter(): express.Router
    • getSingleTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Template>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Template>

    • updateTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Template>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Template>

    Generated using TypeDoc

    \ No newline at end of file +routes/template | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/template

    Index

    Variables

    notOwnerError: ApiError = ...

    Functions

    • createTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Template>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Template>

    • deleteTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Empty>

    • getAllTemplates(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.TemplateList>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.TemplateList>

    • getRouter(): express.Router
    • getSingleTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Template>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Template>

    • updateTemplate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Template>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Template>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_user.html b/backend/docs/modules/routes_user.html index c9f3af27..149d2bb4 100644 --- a/backend/docs/modules/routes_user.html +++ b/backend/docs/modules/routes_user.html @@ -1,42 +1,60 @@ -routes/user | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/user

    Index

    Functions

    • createUserAcceptance(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.PartialUser>
    • +routes/user | backend
      Options
      All
      • Public
      • Public/Protected
      • All
      Menu

      Module routes/user

      Index

      Functions

      • createUserAcceptance(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.PartialUser>
      • Attempts to accept a request for becoming a login_user.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.PartialUser>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • createUserRequest(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Id>
      • createUserPermission(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • +

        Attempts to create a user permission in the system.

        +

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
          +

          The Express.js request to extract all required data from.

          +

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using +Promise.resolve, failures using Promise.reject.

        +
      • createUserRequest(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Id>
      • Attempts to create a new user in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.Id>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • deleteUserRequest(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.PartialUser>
      • deleteUserPermission(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Empty>
      • +

        Attempts to delte a user permission in the system.

        +

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
          +

          The Express.js request to extract all required data from.

          +

        Returns Promise<Responses.Empty>

        See the API documentation. Successes are passed using +Promise.resolve, failures using Promise.reject.

        +
      • deleteUserRequest(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.PartialUser>
      • Attempts to deny a request for becoming a coach.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.PartialUser>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • filterUsers(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.UserList>
      • filterUsers(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.UserList>
      • Attempts to filter users in the system by name, email, status, coach or admin.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.UserList>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getCurrentUser(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.User>
      • getCurrentUser(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.User>
      • Attempts to get all data for a certain student in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.User>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • getRouter(): express.Router
      • getRouter(): express.Router
      • Gets the router for all /user/ related endpoints.

        Returns express.Router

        An Express.js {@link express.Router} routing all /user/ endpoints.

        -
      • listUsers(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.UserList>
      • getYearPermissions(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.UserYearsPermissions[]>
      • +

        Attempts to delte a user permission in the system.

        +

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
          +

          The Express.js request to extract all required data from.

          +

        Returns Promise<Responses.UserYearsPermissions[]>

        See the API documentation. Successes are passed using +Promise.resolve, failures using Promise.reject.

        +
      • listUsers(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.UserList>
      • Attempts to list all students in the system.

        Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

          The Express.js request to extract all required data from.

        Returns Promise<Responses.UserList>

        See the API documentation. Successes are passed using Promise.resolve, failures using Promise.reject.

        -
      • setAccountStatus(person_id: number, stat: account_status_enum, key: string, is_admin: boolean, is_coach: boolean): Promise<Responses.PartialUser>
      • Parameters

        • person_id: number
        • stat: account_status_enum
        • key: string
        • is_admin: boolean
        • is_coach: boolean

        Returns Promise<Responses.PartialUser>

      • userModSelf(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Key>
      • Parameters

        • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

        Returns Promise<Responses.Key>

      Legend

      • Variable
      • Function
      • Type alias
      • Interface

      Settings

      Theme

      Generated using TypeDoc

      \ No newline at end of file +
    • setAccountStatus(person_id: number, stat: account_status_enum, is_admin: boolean, is_coach: boolean): Promise<Responses.PartialUser>
    • Parameters

      • person_id: number
      • stat: account_status_enum
      • is_admin: boolean
      • is_coach: boolean

      Returns Promise<Responses.PartialUser>

    • userModSelf(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>): Promise<Responses.Key>
    • Parameters

      • req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>

      Returns Promise<Responses.Key>

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/docs/modules/routes_verify.html b/backend/docs/modules/routes_verify.html index 72908c6b..396bd69b 100644 --- a/backend/docs/modules/routes_verify.html +++ b/backend/docs/modules/routes_verify.html @@ -1,11 +1,11 @@ -routes/verify | backend
    Options
    All
    • Public
    • Public/Protected
    • All
    Menu

    Module routes/verify

    Index

    Functions

    • getRouter(): express.Router

    Generated using TypeDoc

    \ No newline at end of file diff --git a/backend/endpoints.ts b/backend/endpoints.ts index 816094a3..88e36e8c 100644 --- a/backend/endpoints.ts +++ b/backend/endpoints.ts @@ -40,6 +40,17 @@ export function attach(app: express.Application): void { app.use(home + "/verify", verify.getRouter()); }); + app.use(config.global.preferred + "/coffee", (req, res) => { + res.status(418).send({ + steps: [ + "you try to make coffee", + "I'm a teapot", + "this operation fails :(", + "try again next time :(", + ], + }); + }); + app.use( (req: express.Request, res: express.Response): Promise => util.replyError(res, util.errors.cookNonExistent(req.url)) diff --git a/backend/index.ts b/backend/index.ts index db576000..95ddd889 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -1,61 +1,4 @@ -import body from "body-parser"; -import cors from "cors"; -import express from "express"; -import path from "path"; -import * as config from "./config.json"; -import * as ep from "./endpoints"; -import * as util from "./utility"; -import { createServer } from "http"; -import { Server } from "socket.io"; -import { - ClientToServerEvents, - InterServerEvents, - ServerToClientEvents, - SocketData, -} from "./types"; -import { registerLoginUserHandlers } from "./websocket_events/login_user"; - -const app: express.Application = express(); -const port: number = config.port; -const httpServer = createServer(app); - -// require makes it A LOT easier to use this. Import gives some weird behaviour -// that is not easy to work around -// eslint-disable-next-line @typescript-eslint/no-var-requires -require("dotenv").config({ - path: path.join(__dirname, `./.env.${process.env.NODE_ENV}`), -}); - -const io = new Server< - ClientToServerEvents, - ServerToClientEvents, - InterServerEvents, - SocketData ->(httpServer, { - cors: { - origin: process.env.FRONTEND, - }, - path: "/socket.io", // we locate the place for websockets at `/socket.io` inside the express server -}); - -app.use(body.urlencoded({ extended: true })); -app.use(express.json()); -app.use(cors()); -app.use((req, _, next) => util.logRequest(req, next)); -app.use((req, _, next) => { - util.queryToBody(req); - next(); -}); -ep.attach(app); -config.global.homes.forEach((home) => util.addInvalidVerbs(app, home + "/")); - -/** - * install all the socket.io listeners. - * We do this by using function "register...." that contain the listeners - */ -io.on("connection", (socket) => { - registerLoginUserHandlers(io, socket); -}); +import { httpServer, port } from "./server"; httpServer.listen(port, () => { console.log(`TypeScript with Express diff --git a/backend/jest.config.js b/backend/jest.config.js index 57be77c2..8e87666f 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -3,5 +3,6 @@ module.exports = { preset: "ts-jest", testEnvironment: "node", setupFiles: ["./tests/tests-setup.ts"], - setupFilesAfterEnv: ["./tests/orm_integration/integration_setup.ts"], + // setupFilesAfterEnv: ["./tests/orm_integration/integration_setup.ts"], + testSequencer: "./tests/jest_sequencer.js", }; diff --git a/backend/orm_functions/contract.ts b/backend/orm_functions/contract.ts index 6a2d8679..2b5e0f46 100644 --- a/backend/orm_functions/contract.ts +++ b/backend/orm_functions/contract.ts @@ -103,9 +103,29 @@ export async function contractsByProject(projectId: number) { person: true, }, }, - project_role: true, + project_role: { + select: { + positions: true, + project_id: true, + project_role_id: true, + role_id: true, + role: { + select: { + name: true, + }, + }, + }, + }, contract_status: true, contract_id: true, + login_user: { + select: { + login_user_id: true, + is_admin: true, + is_coach: true, + person: true, + }, + }, }, }); } diff --git a/backend/orm_functions/evaluation.ts b/backend/orm_functions/evaluation.ts index 5de85fe1..2b1a1be1 100644 --- a/backend/orm_functions/evaluation.ts +++ b/backend/orm_functions/evaluation.ts @@ -100,7 +100,7 @@ export async function getLoginUserByEvaluationId(evaluationId: number) { */ export async function getEvaluationByPartiesFor( userId: number, - studentId: number, + studentId: number | undefined, osocId: number ) { return await prisma.evaluation.findMany({ diff --git a/backend/orm_functions/job_application.ts b/backend/orm_functions/job_application.ts index 4123de0e..0678a443 100644 --- a/backend/orm_functions/job_application.ts +++ b/backend/orm_functions/job_application.ts @@ -30,8 +30,7 @@ export async function getStudentEvaluationsTotal(studentId: number) { person: { select: { person_id: true, - firstname: true, - lastname: true, + name: true, email: true, github: true, }, @@ -75,8 +74,7 @@ export async function getStudentEvaluationsFinal(studentId: number) { person: { select: { person_id: true, - firstname: true, - lastname: true, + name: true, email: true, github: true, }, @@ -120,8 +118,7 @@ export async function getStudentEvaluationsTemp(studentId: number) { person: { select: { person_id: true, - firstname: true, - lastname: true, + name: true, email: true, github: true, }, @@ -245,12 +242,15 @@ export async function getLatestJobApplicationOfStudent(studentId: number) { }, orderBy: { // order descending == get newest first - created_at: "desc", + osoc: { + year: "desc", + }, }, include: { attachment: true, job_application_skill: true, applied_role: true, + osoc: true, }, }); } @@ -269,6 +269,7 @@ export async function getJobApplication(jobApplicationId: number) { attachment: true, job_application_skill: true, applied_role: true, + osoc: true, }, }); } @@ -292,3 +293,70 @@ export async function getJobApplicationByYear(year: number) { }, }); } + +/** + * + * @param studentId: the id of the student whose jobapplicatio we are searching + * @param year: the year that we are looking up all the job applications for + * @returns all the job applications associated with the given year + */ +export async function getJobApplicationByYearForStudent( + studentId: number, + year: number +) { + return ( + await prisma.job_application.findMany({ + where: { + osoc: { + year: year, + }, + student_id: studentId, + }, + include: { + attachment: true, + job_application_skill: true, + applied_role: true, + }, + }) + )[0]; // return the 0-th value because there is maximum 1 value! +} + +/** + * + * @param studentId: the student id + * @param year: the year + * @returns all the job applications associated with the given year + */ +export async function getEvaluationsByYearForStudent( + studentId: number, + year: number +) { + return await prisma.job_application.findFirst({ + where: { + student_id: studentId, + osoc: { + year: year, + }, + }, + select: { + evaluation: { + select: { + evaluation_id: true, + decision: true, + motivation: true, + is_final: true, + login_user: { + select: { + person: true, + account_status: true, + login_user_id: true, + person_id: true, + is_admin: true, + is_coach: true, + }, + }, + }, + }, + }, + }); +} diff --git a/backend/orm_functions/login_user.ts b/backend/orm_functions/login_user.ts index c3eecdf5..5b480833 100644 --- a/backend/orm_functions/login_user.ts +++ b/backend/orm_functions/login_user.ts @@ -2,12 +2,14 @@ import prisma from "../prisma/prisma"; import { CreateLoginUser, + DBPagination, FilterBoolean, FilterSort, FilterString, UpdateLoginUser, } from "./orm_types"; -import { account_status_enum } from "@prisma/client"; +import { account_status_enum, Prisma } from "@prisma/client"; +import { deletePersonFromDB } from "./person"; /** * @@ -193,6 +195,20 @@ export async function deleteLoginUserByPersonId(personId: number) { return result; } +/** + * + * @param loginUserId the login user whose info we are deleting from the database + */ +export async function deleteLoginUserFromDB(loginUserId: number) { + // search the personId + const loginUser = await getLoginUserById(loginUserId); + + if (loginUser) { + // call the delete + await deletePersonFromDB(loginUser.person_id); + } +} + /** * * @param loginUserId: the id of the loginUser we are searching @@ -212,8 +228,6 @@ export async function getLoginUserById(loginUserId: number) { * * @param nameFilter name that we are filtering on (or undefined if not filtering on name) * @param emailFilter email that we are filtering on (or undefined if not filtering on email) - * @param coachFilter coachstatus that we are filtering on (or undefined if not filtering on coach) - * @param adminFilter adminstatus that we are filtering on (or undefined if not filtering on admin) * @param nameSort asc or desc if we want to sort on name, undefined if we are not sorting on name * @param emailSort asc or desc if we are sorting on email, undefined if we are not sorting on email * @param statusFilter a given email status to filter on or undefined if we are not filtering on a status @@ -223,39 +237,49 @@ export async function getLoginUserById(loginUserId: number) { */ export async function filterLoginUsers( - nameFilter: FilterString, - emailFilter: FilterString, - nameSort: FilterSort, - emailSort: FilterSort, - statusFilter: account_status_enum | undefined, - isCoach: FilterBoolean, - isAdmin: FilterBoolean + pagination: DBPagination, + nameFilter: FilterString = undefined, + emailFilter: FilterString = undefined, + nameSort: FilterSort = undefined, + emailSort: FilterSort = undefined, + statusFilter: account_status_enum | undefined = undefined, + isCoach: FilterBoolean = undefined, + isAdmin: FilterBoolean = undefined ) { - // execute the query - return await prisma.login_user.findMany({ - where: { - person: { - firstname: { - contains: nameFilter, - mode: "insensitive", - }, - email: { - contains: emailFilter, - mode: "insensitive", - }, + const filter: Prisma.login_userWhereInput = { + person: { + name: { + contains: nameFilter, + mode: "insensitive", + }, + email: { + contains: emailFilter, + mode: "insensitive", }, - account_status: statusFilter, - is_coach: isCoach, - is_admin: isAdmin, }, + account_status: statusFilter, + is_coach: isCoach, + is_admin: isAdmin, + }; + const count = await prisma.login_user.count({ where: filter }); + // execute the query + const data = await prisma.login_user.findMany({ + skip: pagination.currentPage * pagination.pageSize, + take: pagination.pageSize, + where: filter, orderBy: [ - { person: { firstname: nameSort } }, + { person: { name: nameSort } }, { person: { email: emailSort } }, ], include: { person: true, }, }); + + return { + pagination: { page: pagination.currentPage, count: count }, + data: data, + }; } /** @@ -299,3 +323,34 @@ export async function setAdmin(loginUserId: number, isAdmin: boolean) { }, }); } + +/** + * get a list of years that should be visible for the login_user with given id + * @param loginUserId: the id of the loginUser for who we are checking + */ +export async function getOsocYearsForLoginUser(loginUserId: number) { + const years_object = await prisma.login_user.findUnique({ + where: { + login_user_id: loginUserId, + }, + select: { + login_user_osoc: { + select: { + osoc: { + select: { + year: true, + }, + }, + }, + }, + }, + }); + + const years = []; + if (years_object && years_object.login_user_osoc) { + for (const obj of years_object.login_user_osoc) { + years.push(obj.osoc.year); + } + } + return years; +} diff --git a/backend/orm_functions/login_user_osoc.ts b/backend/orm_functions/login_user_osoc.ts new file mode 100644 index 00000000..0996b07a --- /dev/null +++ b/backend/orm_functions/login_user_osoc.ts @@ -0,0 +1,106 @@ +import prisma from "../prisma/prisma"; + +/** + * + * @param loginUserId: the id of the loginUser whose entry for the connection with the osoc edition we are searching + * @param osocId: the id of the osoc edition whose entry for the connection with the login user we are searching + * @returns null if an entry with these values exists, otherwise the entry + */ +export async function getLoginUserOsocByIds( + loginUserId: number, + osocId: number +) { + // will find 0 or 1 entry + const res = await prisma.login_user_osoc.findMany({ + where: { + login_user_id: loginUserId, + osoc_id: osocId, + }, + }); + + if (res.length === 0) { + return null; + } + return res[0]; +} + +/** + * creates an entry in the "in between table" for osoc and login_user. + * An entry in this table indicates that this loginUser should be able to see the osoc edition + * + * @param loginUserId: the id of the loginUser that should be able to see the osoc edition + * @param osocId: the id of the osoc edition that the loginUser should see + */ +export async function addOsocToUser(loginUserId: number, osocId: number) { + const entry = await getLoginUserOsocByIds(loginUserId, osocId); + + // only create new entry if entry does not yet exists + if (entry === null) { + return await prisma.login_user_osoc.create({ + data: { + login_user_id: loginUserId, + osoc_id: osocId, + }, + }); + } +} + +/** + * Delete all connections between the osoc table and loginUser table for a given loginUser + * @param loginUserId: the id of the loginUser whose connections we will delete + */ +export async function deleteOsocsForLoginuser(loginUserId: number) { + return await prisma.login_user_osoc.deleteMany({ + where: { + login_user_id: loginUserId, + }, + }); +} + +/** + * Delete all connections between the osoc table and loginUser table for a given osoc edition + * @param osocId: the id of the osoc whose connections to loginUsers we want to delete + */ +export async function deleteOsocsLoginConnectionFromOsoc(osocId: number) { + return await prisma.login_user_osoc.deleteMany({ + where: { + osoc_id: osocId, + }, + }); +} + +/** + * remove the permissions of an loginUser to see data from this osocEdition + * @param loginUserId: the id of the loginuser + * @param osocId: the id of the osoc edition + */ +export async function removeOsocFromUser(loginUserId: number, osocId: number) { + const entry = await getLoginUserOsocByIds(loginUserId, osocId); + + // only delete if there is an entry + if (entry !== null) { + // will only delete 1 entry because each combination of loginUserId and osocId in this table is unique + return await prisma.login_user_osoc.deleteMany({ + where: { + login_user_id: loginUserId, + osoc_id: osocId, + }, + }); + } +} + +/** + * + * @param loginUserId: the Id of the loginUser + * @returns a promise with inside al list of objects with references to the osoc editions that are visible for the given loginUser + */ +export async function getOsocYearsForLoginUserById(loginUserId: number) { + return await prisma.login_user_osoc.findMany({ + where: { + login_user_id: loginUserId, + }, + include: { + osoc: true, + }, + }); +} diff --git a/backend/orm_functions/orm_types.ts b/backend/orm_functions/orm_types.ts index 77ad8df1..e8891c9e 100644 --- a/backend/orm_functions/orm_types.ts +++ b/backend/orm_functions/orm_types.ts @@ -5,18 +5,20 @@ import { account_status_enum, } from "@prisma/client"; +/***/ +export interface DBPagination { + currentPage: number; + pageSize: number; +} + /** * interface for the object needed to create a person */ export interface CreatePerson { /** - * the person's firstname - */ - firstname: string; - /** - * the person's lastname + * the person's name */ - lastname: string; + name: string; /** * the person's github account, only one of github/email can be used @@ -37,17 +39,13 @@ export interface CreatePerson { */ export interface UpdatePerson { /** - * the person who's info we are updating + * the person whose info we are updating */ personId: number; /** - * undefined if unchanged or new firstname - */ - firstname?: string; - /** - * undefined if unchanged or the new lastname + * undefined if unchanged or new name */ - lastname?: string; + name?: string; /** * undefined if unchanged or the new github */ @@ -367,9 +365,9 @@ export interface CreateProject { */ endDate: Date; /** - * the amount of people who need to assigned to the project + * a short description of the project */ - positions: number; + description: string; } /** @@ -401,9 +399,87 @@ export interface UpdateProject { */ endDate?: Date; /** - * undefined if unchanged or the new number of positions of the project + * undefined if unchanged or the new description of the project + */ + description?: string; +} + +/** + * interface for the filtered projects + */ +export interface FilterProjects { + /** + * the id of the project + */ + project_id: number; + /** + * the name of the project + */ + name: string; + /** + * the id of the osoc edition this project belongs to + */ + osoc_id: number; + /** + * the partner of this project + */ + partner: string; + /** + * the start date of the project + */ + start_date: Date; + /** + * the end date of the project + */ + end_date: Date; + /** + * the amount of people who need to assigned to the project + */ + positions: number; + /** + * the description of this project + */ + description: string; + /** + * the roles of this project + */ + project_role: FilterProjectsRole[]; + /** + * the users who belong to this project + */ + project_user: FilterProjectsLoginUser[]; +} + +/** + * interface for the filtered roles + */ +export interface FilterProjectsRole { + /** + * the number of positions for this role + */ + positions: number; + /** + * the role name + */ + role: { + name: string; + }; + _count: { + contract: number; + }; +} + +/** + * interface for the filtered login users + */ +export interface FilterProjectsLoginUser { + /** + * the login user */ - positions?: number; + login_user: { + login_user_id: number; + is_coach: boolean; + }; } /** @@ -564,7 +640,7 @@ export interface AddStudentToProject { /** * interface for the object needed to create a project user */ -export interface CreateProjectUser { +export interface ProjectUser { /** * the id of the project this user belongs to */ diff --git a/backend/orm_functions/osoc.ts b/backend/orm_functions/osoc.ts index 2a33e09d..e073c9c2 100644 --- a/backend/orm_functions/osoc.ts +++ b/backend/orm_functions/osoc.ts @@ -1,5 +1,12 @@ import prisma from "../prisma/prisma"; -import { UpdateOsoc, FilterNumber, FilterSort } from "./orm_types"; +import { + UpdateOsoc, + FilterNumber, + FilterSort, + DBPagination, +} from "./orm_types"; +import { getOsocYearsForLoginUser } from "./login_user"; +import { deleteOsocsLoginConnectionFromOsoc } from "./login_user_osoc"; /** * @@ -126,7 +133,7 @@ export async function deleteOsocByYear(year: number) { /** * - * @param osoc_id the osoc edition that we are deleting from the database + * @param osocId: the id of the osoc edition we want to delete */ export async function deleteOsocFromDB(osocId: number) { const project_ids = await prisma.project.findMany({ @@ -167,6 +174,9 @@ export async function deleteOsocFromDB(osocId: number) { }, }); + // remove the links between login_user and osoc + await deleteOsocsLoginConnectionFromOsoc(osocId); + // Remove all the linked contracts await prisma.contract.deleteMany({ where: { @@ -257,15 +267,39 @@ export async function getNewestOsoc() { * * @param yearFilter year that we are filtering on (or undefined if not filtering on year) * @param yearSort asc or desc if we are sorting on year, undefined if we are not sorting on year + * @param userId the userId of the user that is searching * @returns the filtered osoc editions with their project count in a promise */ export async function filterOsocs( + pagination: DBPagination, yearFilter: FilterNumber, - yearSort: FilterSort + yearSort: FilterSort, + userId: number ) { - return await prisma.osoc.findMany({ + const visibleYears = await getOsocYearsForLoginUser(userId); + let searchYears; + if (yearFilter !== undefined) { + if (!visibleYears.includes(yearFilter)) { + return Promise.resolve({ + pagination: { page: 0, count: 0 }, + data: [], + }); + } else { + searchYears = [yearFilter]; + } + } else { + searchYears = visibleYears; + } + + const count = await prisma.osoc.count({ where: { year: yearFilter } }); + + const data = await prisma.osoc.findMany({ + skip: pagination.currentPage * pagination.pageSize, + take: pagination.pageSize, where: { - year: yearFilter, + year: { + in: searchYears, + }, }, orderBy: { year: yearSort, @@ -276,4 +310,22 @@ export async function filterOsocs( }, }, }); + + return { + pagination: { page: pagination.currentPage, count: count }, + data: data, + }; +} + +/** + * + * @param osocId: the id of the osoc edition we are searching + * @returns the found osoc edition in a promise + */ +export async function getOsocById(osocId: number) { + return await prisma.osoc.findUnique({ + where: { + osoc_id: osocId, + }, + }); } diff --git a/backend/orm_functions/person.ts b/backend/orm_functions/person.ts index dc1797b2..1d7071d5 100644 --- a/backend/orm_functions/person.ts +++ b/backend/orm_functions/person.ts @@ -9,8 +9,7 @@ import { CreatePerson, UpdatePerson } from "./orm_types"; export async function createPerson(person: CreatePerson) { return await prisma.person.create({ data: { - firstname: person.firstname, - lastname: person.lastname, + name: person.name, github: person.github, email: person.email, github_id: person.github_id, @@ -61,7 +60,7 @@ export async function getPasswordPersonByGithub(github: string) { select: { github: true, person_id: true, - firstname: true, + name: true, login_user: { select: { password: true, @@ -84,14 +83,7 @@ export async function getPasswordPersonByGithub(github: string) { export async function searchPersonByName(name: string) { return await prisma.person.findMany({ where: { - OR: [ - { - firstname: { contains: name }, - }, - { - lastname: { contains: name }, - }, - ], + name: { contains: name }, }, }); } @@ -126,8 +118,7 @@ export async function updatePerson(person: UpdatePerson) { return await prisma.person.update({ where: { person_id: person.personId }, data: { - firstname: person.firstname, - lastname: person.lastname, + name: person.name, github: person.github, email: person.email, }, @@ -142,3 +133,108 @@ export async function updatePerson(person: UpdatePerson) { export async function deletePersonById(personId: number) { return await prisma.person.delete({ where: { person_id: personId } }); } + +/** + * This query executes a full delete of all data associated with the person. + * This includes all student AND login_user data that is associated with this person! + * @param personId: the id of the person we want to delete + * @returns the deleted record from the person-table in a promise or an error in a promise if the person was not found + */ +export async function deletePersonFromDB(personId: number) { + // search the information about the person. We'll need the student_id and login_user_id later on + const person = await prisma.person.findUnique({ + where: { + person_id: personId, + }, + include: { + login_user: true, + student: true, + }, + }); + // the person was found + if (person) { + // the person is a login_user + if (person.login_user) { + const loginUserId = person.login_user.login_user_id; + + // Remove all the linked password reset + await Promise.all([ + prisma.login_user_osoc.deleteMany({ + where: { + login_user_id: loginUserId, + }, + }), + prisma.password_reset.deleteMany({ + where: { + login_user_id: loginUserId, + }, + }), + // Remove all the linked project users + prisma.project_user.deleteMany({ + where: { + login_user_id: loginUserId, + }, + }), + // Remove all the linked sessionkeys + prisma.session_keys.deleteMany({ + where: { + login_user_id: loginUserId, + }, + }), + ]); + await prisma.login_user.delete({ + where: { + login_user_id: loginUserId, + }, + }); + } + + // the person is a student + if (person.student) { + const studentId = person.student.student_id; + + const job_application_ids = await prisma.job_application.findMany({ + where: { + student_id: studentId, + }, + select: { + job_application_id: true, + }, + }); + + // Remove all the linked attachments + await prisma.attachment.deleteMany({ + where: { + job_application_id: { + in: job_application_ids.map( + (X) => X.job_application_id + ), + }, + }, + }); + + await prisma.contract.deleteMany({ + where: { + student_id: studentId, + }, + }); + + // delete the student record + await prisma.student.delete({ + where: { + student_id: studentId, + }, + include: { + person: true, + }, + }); + } + + // delete the person record + await prisma.person.delete({ + where: { + person_id: person.person_id, + }, + }); + } +} diff --git a/backend/orm_functions/project.ts b/backend/orm_functions/project.ts index dd3d0fd7..b54f3157 100644 --- a/backend/orm_functions/project.ts +++ b/backend/orm_functions/project.ts @@ -1,29 +1,31 @@ import prisma from "../prisma/prisma"; +import { Prisma } from "@prisma/client"; import { CreateProject, - UpdateProject, - FilterString, - FilterSort, + DBPagination, FilterBoolean, - FilterNumberArray, + FilterSort, + FilterString, + UpdateProject, } from "./orm_types"; +import { getOsocYearsForLoginUser } from "./login_user"; +import { errors } from "../utility"; /** * * @param project: project object with the needed information */ export async function createProject(project: CreateProject) { - const result = await prisma.project.create({ + return await prisma.project.create({ data: { name: project.name, osoc_id: project.osocId, partner: project.partner, start_date: project.startDate, end_date: project.endDate, - positions: project.positions, + description: project.description, }, }); - return result; } /** @@ -31,8 +33,7 @@ export async function createProject(project: CreateProject) { * @returns a list of all the project objects in the database */ export async function getAllProjects() { - const result = await prisma.project.findMany(); - return result; + return await prisma.project.findMany(); } /** @@ -41,12 +42,14 @@ export async function getAllProjects() { * @returns: object with all the info about this project */ export async function getProjectById(projectId: number) { - const result = prisma.project.findUnique({ + return prisma.project.findUnique({ where: { project_id: projectId, }, + include: { + osoc: true, + }, }); - return result; } /** @@ -55,12 +58,11 @@ export async function getProjectById(projectId: number) { * @returns: object with all the info about this project */ export async function getProjectByName(projectName: string) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { name: projectName, }, }); - return result; } /** @@ -69,12 +71,11 @@ export async function getProjectByName(projectName: string) { * @returns: all projects with all the info */ export async function getProjectsByOsocEdition(osocId: number) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { osoc_id: osocId, }, }); - return result; } /** @@ -83,12 +84,11 @@ export async function getProjectsByOsocEdition(osocId: number) { * @returns all the project objects for that partner */ export async function getProjectsByPartner(partner: string) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { partner: partner, }, }); - return result; } /** @@ -97,12 +97,11 @@ export async function getProjectsByPartner(partner: string) { * @returns all the projects with a matching start date in the database */ export async function getProjectsByStartDate(startDate: Date) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { start_date: startDate, }, }); - return result; } /** @@ -111,14 +110,13 @@ export async function getProjectsByStartDate(startDate: Date) { * @returns all the projects that started after the supplied date */ export async function getProjectsStartedAfterDate(date: Date) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { start_date: { gte: date, }, }, }); - return result; } /** @@ -127,14 +125,13 @@ export async function getProjectsStartedAfterDate(date: Date) { * @returns all the projects that started before the supplied date */ export async function getProjectsStartedBeforeDate(date: Date) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { start_date: { lte: date, }, }, }); - return result; } /** @@ -143,12 +140,11 @@ export async function getProjectsStartedBeforeDate(date: Date) { * @returns all the projects with a matching end date in the database */ export async function getProjectsByEndDate(endDate: Date) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { end_date: endDate, }, }); - return result; } /** @@ -157,14 +153,13 @@ export async function getProjectsByEndDate(endDate: Date) { * @returns all the projects that ended after the supplied date */ export async function getProjectsEndedAfterDate(date: Date) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { end_date: { gte: date, }, }, }); - return result; } /** @@ -173,60 +168,13 @@ export async function getProjectsEndedAfterDate(date: Date) { * @returns all the projects that ended before the supplied date */ export async function getProjectsEndedBeforeDate(date: Date) { - const result = prisma.project.findMany({ + return prisma.project.findMany({ where: { end_date: { lte: date, }, }, }); - return result; -} - -/** - * - * @param positions: this is the number of positions in the project - * @returns all the project objects that have the exact amount of positions - */ -export async function getProjectsByNumberPositions(positions: number) { - const result = prisma.project.findMany({ - where: { - positions: positions, - }, - }); - return result; -} - -/** - * - * @param positions: this is the number of positions in the project - * @returns all the project objects that have less positions - */ -export async function getProjectsLessPositions(positions: number) { - const result = prisma.project.findMany({ - where: { - positions: { - lt: positions, - }, - }, - }); - return result; -} - -/** - * - * @param positions: this is the number of positions in the project - * @returns all the project objects that have more positions - */ -export async function getProjectsMorePositions(positions: number) { - const result = prisma.project.findMany({ - where: { - positions: { - gt: positions, - }, - }, - }); - return result; } /** @@ -235,7 +183,7 @@ export async function getProjectsMorePositions(positions: number) { * @returns the updated entry in the database */ export async function updateProject(project: UpdateProject) { - const result = await prisma.project.update({ + return await prisma.project.update({ where: { project_id: project.projectId, }, @@ -245,10 +193,9 @@ export async function updateProject(project: UpdateProject) { partner: project.partner, start_date: project.startDate, end_date: project.endDate, - positions: project.positions, + description: project.description, }, }); - return result; } /** @@ -257,12 +204,11 @@ export async function updateProject(project: UpdateProject) { * @returns return deleted project, with all its fields */ export async function deleteProject(projectId: number) { - const result = await prisma.project.delete({ + return await prisma.project.delete({ where: { project_id: projectId, }, }); - return result; } /** @@ -271,12 +217,11 @@ export async function deleteProject(projectId: number) { * @returns returns batch payload object, with holds count of number of deleted objects */ export async function deleteProjectByOsocEdition(osocId: number) { - const result = await prisma.project.deleteMany({ + return await prisma.project.deleteMany({ where: { osoc_id: osocId, }, }); - return result; } /** @@ -285,35 +230,58 @@ export async function deleteProjectByOsocEdition(osocId: number) { * @returns returns batch payload object, with holds count of number of deleted objects */ export async function deleteProjectByPartner(partner: string) { - const result = await prisma.project.deleteMany({ + return await prisma.project.deleteMany({ where: { partner: partner, }, }); - return result; } /** - * + * @param page current page and page size * @param projectNameFilter project name that we are filtering on (or undefined if not filtering on name) * @param clientNameFilter client name that we are filtering on (or undefined if not filtering on name) - * @param assignedCoachesFilterArray assigned coaches that we are filtering on (or undefined if not filtering on assigned coaches) * @param fullyAssignedFilter fully assigned status that we are filtering on (or undefined if not filtering on assigned) + * @param osocYearFilter: the osoc year the project belongs to (or undefined if not filtering on year) * @param projectNameSort asc or desc if we want to sort on project name, undefined if we are not sorting on project name * @param clientNameSort asc or desc if we want to sort on client name, undefined if we are not sorting on client name - * @param fullyAssignedSort asc or desc if we are sorting on fully assigned, undefined if we are not sorting on fully assigned + * @param userId the id of the user who searches * @returns the filtered students with their person data and other filter fields in a promise */ export async function filterProjects( + page: DBPagination, projectNameFilter: FilterString, clientNameFilter: FilterString, - assignedCoachesFilterArray: FilterNumberArray, fullyAssignedFilter: FilterBoolean, + osocYearFilter: number | undefined, projectNameSort: FilterSort, clientNameSort: FilterSort, - fullyAssignedSort: FilterSort + userId: number ) { + const yearsAllowedToSee = await getOsocYearsForLoginUser(userId); + + let searchYears; + if (osocYearFilter !== undefined) { + if (!yearsAllowedToSee.includes(osocYearFilter)) { + return Promise.resolve({ + pagination: { page: 0, count: 0 }, + data: [], + }); + } else { + searchYears = [osocYearFilter]; + } + } else { + searchYears = yearsAllowedToSee; + } + const projects = await prisma.project.findMany({ + where: { + osoc: { + year: { + in: searchYears, + }, + }, + }, include: { project_role: { include: { @@ -325,31 +293,35 @@ export async function filterProjects( }, }); - let assignedCoachesArray = undefined; - if (assignedCoachesFilterArray !== undefined) { - assignedCoachesArray = { - some: { - login_user_id: { in: assignedCoachesFilterArray }, + const actualFilter: Prisma.projectWhereInput = { + name: { + contains: projectNameFilter, + mode: "insensitive", + }, + partner: { + contains: clientNameFilter, + mode: "insensitive", + }, + osoc: { + year: { + in: searchYears, }, - }; + }, + }; + + // create the orderby object + let sortObject; + if (projectNameSort === undefined && clientNameSort !== undefined) { + sortObject = [{ name: clientNameSort }]; + } else if (projectNameSort !== undefined && clientNameSort === undefined) { + sortObject = [{ partner: projectNameSort }]; + } else if (projectNameSort !== undefined && clientNameSort !== undefined) { + sortObject = [{ name: projectNameSort }, { partner: clientNameSort }]; } - const filtered_projects = await prisma.project.findMany({ - where: { - name: { - contains: projectNameFilter, - mode: "insensitive", - }, - partner: { - contains: clientNameFilter, - mode: "insensitive", - }, - project_user: assignedCoachesArray, - }, - orderBy: { - name: projectNameSort, - partner: clientNameSort, - }, + let filtered_projects = await prisma.project.findMany({ + where: actualFilter, + orderBy: sortObject, include: { project_user: { select: { @@ -379,72 +351,77 @@ export async function filterProjects( fullyAssignedFilter && filtered_projects.length !== 0 ) { - return filtered_projects.filter((project) => { - const project_found = projects.find( + filtered_projects = filtered_projects.filter((project) => { + const project_found = projects.filter( (elem) => elem.project_id === project.project_id ); - if (project_found != undefined) { - let sum = 0; - for (const c of project_found.project_role) { - sum += c._count.contract; - } - return project.positions === sum; + for (const c of project_found[0].project_role) { + if (c._count.contract < c.positions) return false; } - return false; + return true; }); } - if (fullyAssignedSort == "desc" || fullyAssignedSort == "asc") { - filtered_projects.sort((x, y) => { - const project_x_found = projects.find( - (elem) => elem.project_id === x.project_id - ); - - const project_y_found = projects.find( - (elem) => elem.project_id === y.project_id - ); - - if (project_x_found != undefined && project_y_found != undefined) { - let sum_x = 0; - for (const c of project_x_found.project_role) { - sum_x += c._count.contract; - } + const count = filtered_projects.length; + const start = page.currentPage * page.pageSize; + const end = start + page.pageSize; - let sum_y = 0; - for (const c of project_y_found.project_role) { - sum_y += c._count.contract; - } - - const fullyAssignedX = x.positions === sum_x ? 1 : 0; - const fullyAssignedY = y.positions === sum_y ? 1 : 0; + return { + pagination: { page: page.currentPage, count: count }, + data: filtered_projects.slice(start, end), + }; +} - return fullyAssignedX - fullyAssignedY; - } +/** + * returns the year that a project belongs to + * @param projectId: id of the project whose year we are looking for + */ +export async function getProjectYear(projectId: number) { + const project = await prisma.project.findUnique({ + where: { + project_id: projectId, + }, + select: { + osoc: { + select: { + year: true, + }, + }, + }, + }); - return 0; - }); + if (project === null) { + return Promise.reject(errors.cookInvalidID()); } - if (fullyAssignedSort == "desc") { - filtered_projects.reverse(); - } + return project.osoc.year; +} - /*if (fullyAssignedSort == "asc") { - filtered_projects.sort( - (x, y) => - +(x.positions == projects[x.project_id]._sum.positions) - - +(y.positions == projects[y.project_id]._sum.positions) - ); - } - if (fullyAssignedSort == "desc") { - filtered_projects.sort( - (x, y) => - +(x.positions == projects[x.project_id]._sum.positions) - - +(y.positions == projects[y.project_id]._sum.positions) - ); - filtered_projects.reverse(); - }*/ - return filtered_projects; +/** + * This query executes a full delete of all data associated with the project. + * This includes all projectUser AND projectrole data that is associated with this project! + * @param projectId: the id of the project we want to delete + * @returns the deleted record from the person-table in a promise or an error in a promise if the person was not found + */ +export async function deleteProjectFromDB(projectId: number) { + await Promise.all([ + prisma.project_user.deleteMany({ + where: { + project_id: projectId, + }, + }), + prisma.project_role.deleteMany({ + where: { + project_id: projectId, + }, + }), + ]); + + await prisma.project.delete({ + where: { + project_id: projectId, + }, + }); } diff --git a/backend/orm_functions/project_user.ts b/backend/orm_functions/project_user.ts index c9d0804d..6140618a 100644 --- a/backend/orm_functions/project_user.ts +++ b/backend/orm_functions/project_user.ts @@ -1,12 +1,12 @@ import prisma from "../prisma/prisma"; -import { CreateProjectUser } from "./orm_types"; +import { ProjectUser } from "./orm_types"; /** * * @param projectUser: project user object with the needed information */ -export async function createProjectUser(projectUser: CreateProjectUser) { +export async function createProjectUser(projectUser: ProjectUser) { const result = await prisma.project_user.create({ data: { login_user_id: projectUser.loginUserId, @@ -24,6 +24,7 @@ export async function getUsersFor(project: number) { return await prisma.project_user.findMany({ where: { project_id: project }, select: { + project_user_id: true, login_user: { select: { login_user_id: true, @@ -35,3 +36,17 @@ export async function getUsersFor(project: number) { }, }); } + +/** + * + * @returns a promise with the deleted record inside + * @param projectUser: object that describes the connection between a project and a login user. + */ +export async function deleteProjectUser(projectUser: ProjectUser) { + return await prisma.project_user.deleteMany({ + where: { + project_id: projectUser.projectId, + login_user_id: projectUser.loginUserId, + }, + }); +} diff --git a/backend/orm_functions/student.ts b/backend/orm_functions/student.ts index d92260e7..4731c21d 100644 --- a/backend/orm_functions/student.ts +++ b/backend/orm_functions/student.ts @@ -1,4 +1,4 @@ -import { decision_enum, email_status_enum } from "@prisma/client"; +import { decision_enum, email_status_enum, Prisma } from "@prisma/client"; import prisma from "../prisma/prisma"; import { CreateStudent, @@ -7,7 +7,11 @@ import { FilterBoolean, UpdateStudent, FilterStringArray, + FilterNumber, + DBPagination, } from "./orm_types"; +import { getOsocYearsForLoginUser } from "./login_user"; +import { deletePersonFromDB } from "./person"; /** * @@ -94,6 +98,23 @@ export async function deleteStudent(studentId: number) { }); } +/** + * + * @param studentId the student whose info we are deleting from the database. all related records are deleted too! + */ +export async function deleteStudentFromDB(studentId: number) { + // search the student to get the personId + const student = await prisma.student.findUnique({ + where: { + student_id: studentId, + }, + }); + if (student) { + // call the delete + await deletePersonFromDB(student.person_id); + } +} + /** * * @param gender: This is the gender of the persons we are looking, can be firstname as lastname @@ -112,8 +133,8 @@ export async function searchStudentByGender(gender: string) { /** * - * @param firstNameFilter firstname that we are filtering on (or undefined if not filtering on name) - * @param lastNameFilter firstname that we are filtering on (or undefined if not filtering on name) + * @param pagination object representing the pagination + * @param nameFilter name that we are filtering on (or undefined if not filtering on name) * @param emailFilter email that we are filtering on (or undefined if not filtering on email) * @param roleFilterArray role that we are filtering on (or undefined if not filtering on role) * @param alumniFilter alumni status that we are filtering on (or undefined if not filtering on alumni status) @@ -121,27 +142,40 @@ export async function searchStudentByGender(gender: string) { * @param statusFilter decision status that we are filtering on (or undefined if not filtering on status) * @param emailStatusFilter email status that we are filtering on (or undefined if not filtering on email status) * @param osocYear: the osoc year the application belongs to (or undefined if not filtering on year) - * @param firstNameSort asc or desc if we want to sort on firstname, undefined if we are not sorting on firstname - * @param lastNameSort asc or desc if we want to sort on lastname, undefined if we are not sorting on lastname + * @param nameSort asc or desc if we want to sort on name, undefined if we are not sorting on name * @param emailSort asc or desc if we are sorting on email, undefined if we are not sorting on email - * @param alumniSort asc or desc if we are sorting on alumni status, undefined if we are not sorting on alumni status + * @param loginUserId the id of the loginUser that is searching * @returns the filtered students with their person data and other filter fields in a promise */ export async function filterStudents( - firstNameFilter: FilterString, - lastNameFilter: FilterString, + pagination: DBPagination, + nameFilter: FilterString, emailFilter: FilterString, roleFilterArray: FilterStringArray, alumniFilter: FilterBoolean, coachFilter: FilterBoolean, statusFilter: decision_enum | undefined, - osocYear: number, + osocYear: FilterNumber, emailStatusFilter: email_status_enum | undefined, - firstNameSort: FilterSort, - lastNameSort: FilterSort, + nameSort: FilterSort, emailSort: FilterSort, - alumniSort: FilterSort + loginUserId: number ) { + const yearsAllowedToSee = await getOsocYearsForLoginUser(loginUserId); + let searchYears; + if (osocYear !== undefined) { + if (!yearsAllowedToSee.includes(osocYear)) { + return Promise.resolve({ + pagination: { page: 0, count: 0 }, + data: [], + }); + } else { + searchYears = [osocYear]; + } + } else { + searchYears = yearsAllowedToSee; + } + // manually create filter object for evaluation because evaluation doesn't need to exist // and then the whole object needs to be undefined let evaluationFilter; @@ -149,56 +183,55 @@ export async function filterStudents( evaluationFilter = { some: { decision: statusFilter, + is_final: true, }, }; } else { evaluationFilter = undefined; } - console.log(alumniFilter); - return await prisma.student.findMany({ - where: { - job_application: { - some: { - email_status: emailStatusFilter, - student_coach: coachFilter, - osoc: { - year: osocYear, + const filter: Prisma.studentWhereInput = { + job_application: { + some: { + email_status: emailStatusFilter, + student_coach: coachFilter, + osoc: { + year: { + in: searchYears, }, - applied_role: { - some: { - role: { - name: { in: roleFilterArray }, - }, + }, + applied_role: { + some: { + role: { + name: { in: roleFilterArray }, }, }, - evaluation: evaluationFilter, }, + evaluation: evaluationFilter, }, - person: { - firstname: { - contains: firstNameFilter, - mode: "insensitive", - }, - lastname: { - contains: lastNameFilter, - mode: "insensitive", - }, - email: { - contains: emailFilter, - mode: "insensitive", - }, - }, - alumni: alumniFilter, }, - orderBy: { - person: { - firstname: firstNameSort, - lastname: lastNameSort, - email: emailSort, + person: { + name: { + contains: nameFilter, + mode: "insensitive", + }, + email: { + contains: emailFilter, + mode: "insensitive", }, - alumni: alumniSort, }, + alumni: alumniFilter, + }; + + const count = await prisma.student.count({ where: filter }); + const data = await prisma.student.findMany({ + where: filter, + skip: pagination.currentPage * pagination.pageSize, + take: pagination.pageSize, + orderBy: [ + { person: { name: nameSort } }, + { person: { email: emailSort } }, + ], include: { person: true, job_application: { @@ -222,4 +255,38 @@ export async function filterStudents( }, }, }); + + return { + pagination: { page: pagination.currentPage, count: count }, + data: data, + }; +} + +/** + * @param studentId: the id of the student whose job application years we are searching + * @returns a list of all the years the student has applied for + */ +export async function getAppliedYearsForStudent(studentId: number) { + const student = await prisma.student.findUnique({ + where: { + student_id: studentId, + }, + select: { + job_application: { + select: { + osoc: { + select: { + year: true, + }, + }, + }, + }, + }, + }); + + if (student === null) { + return []; + } + + return student.job_application.map((app) => app.osoc.year); } diff --git a/backend/package-lock.json b/backend/package-lock.json index 7fa907cb..dcb5178e 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -10,27 +10,30 @@ "license": "ISC", "dependencies": { "@jest-mock/express": "^1.4.5", + "@jest/test-sequencer": "^28.0.2", "@prisma/client": "^3.10.0", + "@types/bcrypt": "^5.0.0", "@types/cors": "^2.8.12", "@types/express": "^4.17.13", "@types/node": "^17.0.21", "@types/nodemailer": "^6.4.4", "@types/uuid": "^8.3.4", "axios": "^0.27.0", + "bcrypt": "^5.0.1", "body-parser": "^1.19.2", "cors": "^2.8.5", "cross-env": "^7.0.3", "express": "^4.17.3", "googleapis": "^100.0.0", "nodemailer": "^6.7.3", - "passport": "^0.5.2", - "prisma": "3.13", + "prisma": "3.14", "socket.io": "^4.4.1", "ts-jest": "^27.1.3", "validator": "^13.7.0" }, "devDependencies": { "@types/jest": "^27.4.1", + "@types/supertest": "^2.0.12", "@types/validator": "^13.7.0", "callable-instance": "^2.0.0", "dotenv-cli": "^5.0.0", @@ -38,7 +41,9 @@ "jest": "^27.5.1", "jest-mock-extended": "^2.0.4", "node-ts": "^5.1.2", + "nodemailer-mock": "^1.5.12", "nodemon": "^2.0.15", + "supertest": "^6.2.3", "ts-node": "^10.7.0", "typedoc": "^0.22.13", "typescript": "^4.5.5", @@ -949,6 +954,17 @@ } } }, + "node_modules/@jest/schemas": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.0.2.tgz", + "integrity": "sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==", + "dependencies": { + "@sinclair/typebox": "^0.23.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, "node_modules/@jest/source-map": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", @@ -977,17 +993,208 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", + "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", "dependencies": { - "@jest/test-result": "^27.5.1", + "@jest/test-result": "^28.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" + "jest-haste-map": "^28.1.0", + "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/console": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", + "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", + "dependencies": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/test-result": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", + "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "dependencies": { + "@jest/console": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/types": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", + "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "dependencies": { + "@jest/schemas": "^28.0.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/test-sequencer/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/test-sequencer/node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==" + }, + "node_modules/@jest/test-sequencer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-haste-map": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", + "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "dependencies": { + "@jest/types": "^28.1.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-message-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", + "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", + "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "dependencies": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-worker": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", + "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/pretty-format": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", + "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "dependencies": { + "@jest/schemas": "^28.0.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==" + }, + "node_modules/@jest/test-sequencer/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/@jest/transform": { @@ -1052,6 +1259,53 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1088,12 +1342,12 @@ } }, "node_modules/@prisma/client": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.13.0.tgz", - "integrity": "sha512-lnEA2tTyVbO5mS1ehmHJQKBDiKB8shaR6s3azwj3Azfi5XHIfnqmkolLCvUeFYnkDCNVzGXJpUgKwQt/UOOYVQ==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.14.0.tgz", + "integrity": "sha512-atb41UpgTR1MCst0VIbiHTMw8lmXnwUvE1KyUCAkq08+wJyjRE78Due+nSf+7uwqQn+fBFYVmoojtinhlLOSaA==", "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b" + "@prisma/engines-version": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a" }, "engines": { "node": ">=12.6" @@ -1108,15 +1362,15 @@ } }, "node_modules/@prisma/engines": { - "version": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b.tgz", - "integrity": "sha512-Ip9CcCeUocH61eXu4BUGpvl5KleQyhcUVLpWCv+0ZmDv44bFaDpREqjGHHdRupvPN/ugB6gTlD9b9ewdj02yVA==", + "version": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a.tgz", + "integrity": "sha512-LwZvI3FY6f43xFjQNRuE10JM5R8vJzFTSmbV9X0Wuhv9kscLkjRlZt0BEoiHmO+2HA3B3xxbMfB5du7ZoSFXGg==", "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b.tgz", - "integrity": "sha512-TGp9rvgJIKo8NgvAHSwOosbut9mTA7VC6/rpQI9gh+ySSRjdQFhbGyNUiOcQrlI9Ob2DWeO7y4HEnhdKxYiECg==" + "version": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a.tgz", + "integrity": "sha512-D+yHzq4a2r2Rrd0ZOW/mTZbgDIkUkD8ofKgusEI1xPiZz60Daks+UM7Me2ty5FzH3p/TgyhBpRrfIHx+ha20RQ==" }, "node_modules/@rauschma/stringio": { "version": "1.4.0", @@ -1133,6 +1387,11 @@ "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", "dev": true }, + "node_modules/@sinclair/typebox": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", + "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==" + }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -1247,6 +1506,14 @@ "@babel/types": "^7.3.0" } }, + "node_modules/@types/bcrypt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", + "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -1274,6 +1541,12 @@ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" }, + "node_modules/@types/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", + "dev": true + }, "node_modules/@types/cors": { "version": "2.8.12", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", @@ -1330,9 +1603,9 @@ } }, "node_modules/@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "version": "27.5.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.0.tgz", + "integrity": "sha512-9RBFx7r4k+msyj/arpfaa0WOOEcaAZNmN+j80KFbFCoSqCJGHTz7YMAMGQW9Xmqm5w6l5c25vbSjMwlikJi5+g==", "devOptional": true, "dependencies": { "jest-matcher-utils": "^27.0.0", @@ -1351,9 +1624,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/node": { - "version": "17.0.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", - "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==" + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz", + "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==" }, "node_modules/@types/nodemailer": { "version": "6.4.4", @@ -1392,6 +1665,25 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, + "node_modules/@types/superagent": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.15.tgz", + "integrity": "sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==", + "dev": true, + "dependencies": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "node_modules/@types/supertest": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz", + "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==", + "dev": true, + "dependencies": { + "@types/superagent": "*" + } + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -1582,8 +1874,7 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/abort-controller": { "version": "3.0.0", @@ -1783,6 +2074,23 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1819,6 +2127,12 @@ "node": ">=8" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1965,6 +2279,19 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/bignumber.js": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", @@ -2268,6 +2595,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -2340,6 +2675,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2378,6 +2721,11 @@ "node": ">=8" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -2423,6 +2771,12 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "node_modules/cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -2580,6 +2934,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2597,6 +2956,14 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2605,6 +2972,16 @@ "node": ">=8" } }, + "node_modules/dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -2953,9 +3330,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "26.1.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.5.tgz", - "integrity": "sha512-su89aDuljL9bTjEufTXmKUMSFe2kZUL9bi7+woq+C2ukHZordhtfPm4Vg+tdioHBaKf8v3/FXW9uV0ksqhYGFw==", + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.2.2.tgz", + "integrity": "sha512-etSFZ8VIFX470aA6kTqDPhIq7YWe0tjBcboFNV3WeiC18PJ/AVonGhuTwlmuz2fBkH8FJHA7JQ4k7GsQIj1Gew==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" @@ -3321,9 +3698,9 @@ } }, "node_modules/express": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", - "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -3407,6 +3784,12 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "node_modules/fast-text-encoding": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", @@ -3535,6 +3918,33 @@ "node": ">= 6" } }, + "node_modules/formidable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.0.1.tgz", + "integrity": "sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==", + "dev": true, + "dependencies": { + "dezalgo": "1.0.3", + "hexoid": "1.0.0", + "once": "1.4.0", + "qs": "6.9.3" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/formidable/node_modules/qs": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz", + "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3551,6 +3961,17 @@ "node": ">= 0.6" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3581,6 +4002,25 @@ "dev": true, "peer": true }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/gaxios": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", @@ -3862,6 +4302,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "node_modules/has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", @@ -3871,6 +4316,15 @@ "node": ">=8" } }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -4515,6 +4969,20 @@ } } }, + "node_modules/jest-config/node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/jest-config/node_modules/ci-info": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", @@ -4722,15 +5190,15 @@ } }, "node_modules/jest-mock-extended": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-2.0.5.tgz", - "integrity": "sha512-cQjKRqzZ/hUyy3AdmB7Aa+0DB45dt/eEApwfZFZzup9oefGnw2QodW/BLR39aCpPkK0Qb54P5OKYRXJ98kQ8cQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-2.0.6.tgz", + "integrity": "sha512-KoDdjqwIp2phaOWB0hr4O+9HF7hIJx7O+Reefi3iGrNhUpzVkod9UozYTSanvbNvjFYIEH6noA2tIjc8IDpadw==", "dev": true, "dependencies": { "ts-essentials": "^7.0.3" }, "peerDependencies": { - "jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0", + "jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0", "typescript": "^3.0.0 || ^4.0.0" } }, @@ -5411,6 +5879,40 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "node_modules/minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5429,6 +5931,11 @@ "node": ">= 0.6" } }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -5505,17 +6012,50 @@ "dev": true }, "node_modules/nodemailer": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz", - "integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.5.tgz", + "integrity": "sha512-6VtMpwhsrixq1HDYSBBHvW0GwiWawE75dS3oal48VqRhUvKJNnKnJo2RI/bCVQubj1vgrgscMNW4DHaD6xtMCg==", "engines": { "node": ">=6.0.0" } }, + "node_modules/nodemailer-mock": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/nodemailer-mock/-/nodemailer-mock-1.5.12.tgz", + "integrity": "sha512-Muymd+qvTswEExCys01D11JW2ugHN2mzDaq3dfct546hmmk+Wro3sK3lVSoUZP7x53cOHv1iX3C51mL9IlY8KA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "nodemailer": "^6.x" + } + }, + "node_modules/nodemailer-mock/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemailer-mock/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz", + "integrity": "sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -5599,6 +6139,17 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", @@ -5778,30 +6329,6 @@ "node": ">= 0.8" } }, - "node_modules/passport": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.2.tgz", - "integrity": "sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw==", - "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5845,11 +6372,6 @@ "node": ">=8" } }, - "node_modules/pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -5927,13 +6449,12 @@ } }, "node_modules/prisma": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-3.13.0.tgz", - "integrity": "sha512-oO1auBnBtieGdiN+57IgsA9Vr7Sy4HkILi1KSaUG4mpKfEbnkTGnLOxAqjLed+K2nsG/GtE1tJBtB7JxN1a78Q==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-3.14.0.tgz", + "integrity": "sha512-l9MOgNCn/paDE+i1K2fp9NZ+Du4trzPTJsGkaQHVBufTGqzoYHuNk8JfzXuIn0Gte6/ZjyKj652Jq/Lc1tp2yw==", "hasInstallScript": true, "dependencies": { - "@prisma/engines": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b", - "ts-pattern": "^4.0.1" + "@prisma/engines": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a" }, "bin": { "prisma": "build/index.js", @@ -6090,6 +6611,19 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6353,6 +6887,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -6420,9 +6959,9 @@ } }, "node_modules/socket.io": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.0.tgz", - "integrity": "sha512-slTYqU2jCgMjXwresG8grhUi/cC6GjzmcfqArzaH3BN/9I/42eZk9yamNvZJdBfTubkjEdKAKs12NEztId+bUA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.1.tgz", + "integrity": "sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", @@ -6536,6 +7075,14 @@ "node": ">= 0.8" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -6597,6 +7144,105 @@ "node": ">=0.10.0" } }, + "node_modules/superagent": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.3.tgz", + "integrity": "sha512-WA6et4nAvgBCS73lJvv1D0ssI5uk5Gh+TGN/kNe+B608EtcVs/yzfl+OLXTzDs7tOBDIpvgh/WUs1K2OK1zTeQ==", + "dev": true, + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.3", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.0.1", + "methods": "^1.1.2", + "mime": "^2.5.0", + "qs": "^6.10.3", + "readable-stream": "^3.6.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/superagent/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/superagent/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/superagent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/superagent/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/supertest": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.2.3.tgz", + "integrity": "sha512-3GSdMYTMItzsSYjnIcljxMVZKPW1J9kYHZY+7yLfD0wpPwww97GeImZC1oOk0S5+wYl2niJwuFusBJqwLqYM3g==", + "dev": true, + "dependencies": { + "methods": "^1.1.2", + "superagent": "^7.1.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6655,6 +7301,22 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -6880,11 +7542,6 @@ } } }, - "node_modules/ts-pattern": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-4.0.2.tgz", - "integrity": "sha512-eHqR/7A6fcw05vCOfnL6RwgGJbVi9G/YHTdYdjYmElhDdJ1SMn7pWs+6+YuxygaFwQS/g+cIDlu+UD8IVpur1A==" - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -7001,9 +7658,9 @@ } }, "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7116,6 +7773,11 @@ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -7269,6 +7931,14 @@ "node": ">= 8" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", @@ -8085,6 +8755,14 @@ "v8-to-istanbul": "^8.1.0" } }, + "@jest/schemas": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.0.2.tgz", + "integrity": "sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==", + "requires": { + "@sinclair/typebox": "^0.23.3" + } + }, "@jest/source-map": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", @@ -8107,14 +8785,163 @@ } }, "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", + "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", "requires": { - "@jest/test-result": "^27.5.1", + "@jest/test-result": "^28.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" + "jest-haste-map": "^28.1.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/console": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", + "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0" + } + }, + "@jest/test-result": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", + "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "requires": { + "@jest/console": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", + "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "requires": { + "@jest/schemas": "^28.0.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + }, + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jest-haste-map": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", + "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "requires": { + "@jest/types": "^28.1.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", + "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==" + }, + "jest-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", + "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-worker": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", + "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "pretty-format": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", + "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "requires": { + "@jest/schemas": "^28.0.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==" + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "@jest/transform": { @@ -8170,6 +8997,40 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "requires": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "dependencies": { + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "requires": { + "abbrev": "1" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -8197,22 +9058,22 @@ } }, "@prisma/client": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.13.0.tgz", - "integrity": "sha512-lnEA2tTyVbO5mS1ehmHJQKBDiKB8shaR6s3azwj3Azfi5XHIfnqmkolLCvUeFYnkDCNVzGXJpUgKwQt/UOOYVQ==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.14.0.tgz", + "integrity": "sha512-atb41UpgTR1MCst0VIbiHTMw8lmXnwUvE1KyUCAkq08+wJyjRE78Due+nSf+7uwqQn+fBFYVmoojtinhlLOSaA==", "requires": { - "@prisma/engines-version": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b" + "@prisma/engines-version": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a" } }, "@prisma/engines": { - "version": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b.tgz", - "integrity": "sha512-Ip9CcCeUocH61eXu4BUGpvl5KleQyhcUVLpWCv+0ZmDv44bFaDpREqjGHHdRupvPN/ugB6gTlD9b9ewdj02yVA==" + "version": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a.tgz", + "integrity": "sha512-LwZvI3FY6f43xFjQNRuE10JM5R8vJzFTSmbV9X0Wuhv9kscLkjRlZt0BEoiHmO+2HA3B3xxbMfB5du7ZoSFXGg==" }, "@prisma/engines-version": { - "version": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b.tgz", - "integrity": "sha512-TGp9rvgJIKo8NgvAHSwOosbut9mTA7VC6/rpQI9gh+ySSRjdQFhbGyNUiOcQrlI9Ob2DWeO7y4HEnhdKxYiECg==" + "version": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a.tgz", + "integrity": "sha512-D+yHzq4a2r2Rrd0ZOW/mTZbgDIkUkD8ofKgusEI1xPiZz60Daks+UM7Me2ty5FzH3p/TgyhBpRrfIHx+ha20RQ==" }, "@rauschma/stringio": { "version": "1.4.0", @@ -8231,6 +9092,11 @@ } } }, + "@sinclair/typebox": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", + "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -8333,6 +9199,14 @@ "@babel/types": "^7.3.0" } }, + "@types/bcrypt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", + "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "requires": { + "@types/node": "*" + } + }, "@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -8360,6 +9234,12 @@ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" }, + "@types/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", + "dev": true + }, "@types/cors": { "version": "2.8.12", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", @@ -8416,9 +9296,9 @@ } }, "@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "version": "27.5.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.0.tgz", + "integrity": "sha512-9RBFx7r4k+msyj/arpfaa0WOOEcaAZNmN+j80KFbFCoSqCJGHTz7YMAMGQW9Xmqm5w6l5c25vbSjMwlikJi5+g==", "devOptional": true, "requires": { "jest-matcher-utils": "^27.0.0", @@ -8437,9 +9317,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "@types/node": { - "version": "17.0.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", - "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==" + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz", + "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==" }, "@types/nodemailer": { "version": "6.4.4", @@ -8478,6 +9358,25 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, + "@types/superagent": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.15.tgz", + "integrity": "sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==", + "dev": true, + "requires": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "@types/supertest": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz", + "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==", + "dev": true, + "requires": { + "@types/superagent": "*" + } + }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -8609,8 +9508,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "abort-controller": { "version": "3.0.0", @@ -8751,6 +9649,20 @@ "picomatch": "^2.0.4" } }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -8781,6 +9693,12 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -8888,6 +9806,15 @@ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" }, + "bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + } + }, "bignumber.js": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", @@ -9106,6 +10033,11 @@ "readdirp": "~3.6.0" } }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -9165,6 +10097,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -9197,6 +10134,11 @@ "xdg-basedir": "^4.0.0" } }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, "content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -9235,6 +10177,12 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -9358,6 +10306,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -9368,11 +10321,26 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -9744,9 +10712,9 @@ } }, "eslint-plugin-jest": { - "version": "26.1.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.5.tgz", - "integrity": "sha512-su89aDuljL9bTjEufTXmKUMSFe2kZUL9bi7+woq+C2ukHZordhtfPm4Vg+tdioHBaKf8v3/FXW9uV0ksqhYGFw==", + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.2.2.tgz", + "integrity": "sha512-etSFZ8VIFX470aA6kTqDPhIq7YWe0tjBcboFNV3WeiC18PJ/AVonGhuTwlmuz2fBkH8FJHA7JQ4k7GsQIj1Gew==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" @@ -9882,9 +10850,9 @@ } }, "express": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", - "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -9961,6 +10929,12 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "fast-text-encoding": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", @@ -10057,6 +11031,26 @@ "mime-types": "^2.1.12" } }, + "formidable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.0.1.tgz", + "integrity": "sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==", + "dev": true, + "requires": { + "dezalgo": "1.0.3", + "hexoid": "1.0.0", + "once": "1.4.0", + "qs": "6.9.3" + }, + "dependencies": { + "qs": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz", + "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==", + "dev": true + } + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -10067,6 +11061,14 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -10090,6 +11092,22 @@ "dev": true, "peer": true }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + } + }, "gaxios": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", @@ -10293,12 +11311,23 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, + "hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true + }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -10763,6 +11792,17 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "requires": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + } + }, "ci-info": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", @@ -10928,9 +11968,9 @@ } }, "jest-mock-extended": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-2.0.5.tgz", - "integrity": "sha512-cQjKRqzZ/hUyy3AdmB7Aa+0DB45dt/eEApwfZFZzup9oefGnw2QodW/BLR39aCpPkK0Qb54P5OKYRXJ98kQ8cQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-2.0.6.tgz", + "integrity": "sha512-KoDdjqwIp2phaOWB0hr4O+9HF7hIJx7O+Reefi3iGrNhUpzVkod9UozYTSanvbNvjFYIEH6noA2tIjc8IDpadw==", "dev": true, "requires": { "ts-essentials": "^7.0.3" @@ -11468,6 +12508,28 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -11483,6 +12545,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -11546,14 +12613,41 @@ } }, "nodemailer": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz", - "integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==" + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.5.tgz", + "integrity": "sha512-6VtMpwhsrixq1HDYSBBHvW0GwiWawE75dS3oal48VqRhUvKJNnKnJo2RI/bCVQubj1vgrgscMNW4DHaD6xtMCg==" + }, + "nodemailer-mock": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/nodemailer-mock/-/nodemailer-mock-1.5.12.tgz", + "integrity": "sha512-Muymd+qvTswEExCys01D11JW2ugHN2mzDaq3dfct546hmmk+Wro3sK3lVSoUZP7x53cOHv1iX3C51mL9IlY8KA==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "nodemailer": "^6.x" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } }, "nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz", + "integrity": "sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w==", "dev": true, "requires": { "chokidar": "^3.5.2", @@ -11613,6 +12707,17 @@ "path-key": "^3.0.0" } }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", @@ -11743,20 +12848,6 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, - "passport": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.2.tgz", - "integrity": "sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw==", - "requires": { - "passport-strategy": "1.x.x", - "pause": "0.0.1" - } - }, - "passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11788,11 +12879,6 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -11845,12 +12931,11 @@ } }, "prisma": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-3.13.0.tgz", - "integrity": "sha512-oO1auBnBtieGdiN+57IgsA9Vr7Sy4HkILi1KSaUG4mpKfEbnkTGnLOxAqjLed+K2nsG/GtE1tJBtB7JxN1a78Q==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-3.14.0.tgz", + "integrity": "sha512-l9MOgNCn/paDE+i1K2fp9NZ+Du4trzPTJsGkaQHVBufTGqzoYHuNk8JfzXuIn0Gte6/ZjyKj652Jq/Lc1tp2yw==", "requires": { - "@prisma/engines": "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b", - "ts-pattern": "^4.0.1" + "@prisma/engines": "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a" } }, "prompts": { @@ -11961,6 +13046,16 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -12139,6 +13234,11 @@ "send": "0.18.0" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -12194,9 +13294,9 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "socket.io": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.0.tgz", - "integrity": "sha512-slTYqU2jCgMjXwresG8grhUi/cC6GjzmcfqArzaH3BN/9I/42eZk9yamNvZJdBfTubkjEdKAKs12NEztId+bUA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.1.tgz", + "integrity": "sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==", "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", @@ -12283,6 +13383,14 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -12326,6 +13434,78 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, + "superagent": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.3.tgz", + "integrity": "sha512-WA6et4nAvgBCS73lJvv1D0ssI5uk5Gh+TGN/kNe+B608EtcVs/yzfl+OLXTzDs7tOBDIpvgh/WUs1K2OK1zTeQ==", + "dev": true, + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.3", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.0.1", + "methods": "^1.1.2", + "mime": "^2.5.0", + "qs": "^6.10.3", + "readable-stream": "^3.6.0", + "semver": "^7.3.7" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "supertest": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.2.3.tgz", + "integrity": "sha512-3GSdMYTMItzsSYjnIcljxMVZKPW1J9kYHZY+7yLfD0wpPwww97GeImZC1oOk0S5+wYl2niJwuFusBJqwLqYM3g==", + "dev": true, + "requires": { + "methods": "^1.1.2", + "superagent": "^7.1.3" + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -12368,6 +13548,19 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -12508,11 +13701,6 @@ "yn": "3.1.1" } }, - "ts-pattern": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-4.0.2.tgz", - "integrity": "sha512-eHqR/7A6fcw05vCOfnL6RwgGJbVi9G/YHTdYdjYmElhDdJ1SMn7pWs+6+YuxygaFwQS/g+cIDlu+UD8IVpur1A==" - }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -12598,9 +13786,9 @@ } }, "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==" }, "undefsafe": { "version": "2.0.5", @@ -12684,6 +13872,11 @@ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -12806,6 +13999,14 @@ "isexe": "^2.0.0" } }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", diff --git a/backend/package.json b/backend/package.json index 1efe3e50..20fb80bb 100644 --- a/backend/package.json +++ b/backend/package.json @@ -11,34 +11,37 @@ "dockerIntegration:up": "docker-compose -f docker-compose.integrationtest.yml up -d --build", "docker:down": "docker-compose down", "integrationTests": "npm run dockerIntegration:up && npm run migrate:postgres && jest -i", - "test": "jest", + "test": "jest -i", "coverage": "npm run dockerIntegration:up && npm run migrate:postgres && jest -i --coverage" }, "author": "", "license": "ISC", "dependencies": { "@jest-mock/express": "^1.4.5", + "@jest/test-sequencer": "^28.0.2", "@prisma/client": "^3.10.0", + "@types/bcrypt": "^5.0.0", "@types/cors": "^2.8.12", "@types/express": "^4.17.13", "@types/node": "^17.0.21", "@types/nodemailer": "^6.4.4", "@types/uuid": "^8.3.4", "axios": "^0.27.0", + "bcrypt": "^5.0.1", "body-parser": "^1.19.2", "cors": "^2.8.5", "cross-env": "^7.0.3", "express": "^4.17.3", "googleapis": "^100.0.0", "nodemailer": "^6.7.3", - "passport": "^0.5.2", - "prisma": "3.13", + "prisma": "3.14", "socket.io": "^4.4.1", "ts-jest": "^27.1.3", "validator": "^13.7.0" }, "devDependencies": { "@types/jest": "^27.4.1", + "@types/supertest": "^2.0.12", "@types/validator": "^13.7.0", "callable-instance": "^2.0.0", "dotenv-cli": "^5.0.0", @@ -46,7 +49,9 @@ "jest": "^27.5.1", "jest-mock-extended": "^2.0.4", "node-ts": "^5.1.2", + "nodemailer-mock": "^1.5.12", "nodemon": "^2.0.15", + "supertest": "^6.2.3", "ts-node": "^10.7.0", "typedoc": "^0.22.13", "typescript": "^4.5.5", diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index ab2a317c..42273819 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -25,30 +25,30 @@ model attachment { model contract { contract_id Int @id @default(autoincrement()) - student_id Int @default(autoincrement()) - project_role_id Int @default(autoincrement()) + student_id Int? + project_role_id Int? information String? - created_by_login_user_id Int @default(autoincrement()) + created_by_login_user_id Int? contract_status contract_status_enum - login_user login_user @relation(fields: [created_by_login_user_id], references: [login_user_id], onDelete: NoAction, onUpdate: NoAction) - project_role project_role @relation(fields: [project_role_id], references: [project_role_id], onDelete: NoAction, onUpdate: NoAction) - student student @relation(fields: [student_id], references: [student_id], onDelete: NoAction, onUpdate: NoAction) + login_user login_user? @relation(fields: [created_by_login_user_id], references: [login_user_id], onUpdate: NoAction) + project_role project_role? @relation(fields: [project_role_id], references: [project_role_id], onUpdate: NoAction) + student student? @relation(fields: [student_id], references: [student_id], onUpdate: NoAction) } model evaluation { evaluation_id Int @id @default(autoincrement()) - login_user_id Int @default(autoincrement()) + login_user_id Int? job_application_id Int @default(autoincrement()) decision decision_enum motivation String? is_final Boolean job_application job_application @relation(fields: [job_application_id], references: [job_application_id], onDelete: NoAction, onUpdate: NoAction) - login_user login_user @relation(fields: [login_user_id], references: [login_user_id], onDelete: NoAction, onUpdate: NoAction) + login_user login_user? @relation(fields: [login_user_id], references: [login_user_id], onUpdate: NoAction) } model job_application { job_application_id Int @id @default(autoincrement()) - student_id Int @default(autoincrement()) + student_id Int? student_volunteer_info String responsibilities String? fun_fact String @@ -62,7 +62,7 @@ model job_application { email_status email_status_enum created_at DateTime @db.Timestamptz(6) osoc osoc @relation(fields: [osoc_id], references: [osoc_id], onDelete: NoAction, onUpdate: NoAction) - student student @relation(fields: [student_id], references: [student_id], onDelete: NoAction, onUpdate: NoAction) + student student? @relation(fields: [student_id], references: [student_id], onUpdate: NoAction) applied_role applied_role[] attachment attachment[] evaluation evaluation[] @@ -88,25 +88,27 @@ model language { } model login_user { - login_user_id Int @id @default(autoincrement()) - person_id Int @unique @default(autoincrement()) - password String? - is_admin Boolean - is_coach Boolean - account_status account_status_enum - person person @relation(fields: [person_id], references: [person_id], onDelete: NoAction, onUpdate: NoAction) - contract contract[] - evaluation evaluation[] - password_reset password_reset? - project_user project_user[] - session_keys session_keys[] - template_email template_email[] + login_user_id Int @id @default(autoincrement()) + person_id Int @unique @default(autoincrement()) + password String? @db.VarChar(60) + is_admin Boolean + is_coach Boolean + account_status account_status_enum + person person @relation(fields: [person_id], references: [person_id], onDelete: NoAction, onUpdate: NoAction) + contract contract[] + evaluation evaluation[] + login_user_osoc login_user_osoc[] + password_reset password_reset? + project_user project_user[] + session_keys session_keys[] + template_email template_email[] } model osoc { osoc_id Int @id @default(autoincrement()) year Int @unique @db.SmallInt job_application job_application[] + login_user_osoc login_user_osoc[] project project[] } @@ -114,8 +116,7 @@ model person { person_id Int @id @default(autoincrement()) email String? @unique @db.VarChar(320) github String? @unique - firstname String - lastname String + name String github_id String? @unique login_user login_user? student student? @@ -129,7 +130,6 @@ model project { description String? start_date DateTime @db.Date end_date DateTime @db.Date - positions Int @db.SmallInt osoc osoc @relation(fields: [osoc_id], references: [osoc_id], onDelete: NoAction, onUpdate: NoAction) project_role project_role[] project_user project_user[] @@ -190,17 +190,27 @@ model password_reset { } model template_email { - template_email_id Int @id @default(autoincrement()) - owner_id Int @default(autoincrement()) + template_email_id Int @id @default(autoincrement()) + owner_id Int? name String content String subject String? cc String? - login_user login_user @relation(fields: [owner_id], references: [login_user_id], onDelete: NoAction, onUpdate: NoAction) + login_user login_user? @relation(fields: [owner_id], references: [login_user_id], onUpdate: NoAction) @@unique([owner_id, name]) } +model login_user_osoc { + login_user_osoc_id Int @id @default(autoincrement()) + login_user_id Int + osoc_id Int + login_user login_user @relation(fields: [login_user_id], references: [login_user_id], onDelete: NoAction, onUpdate: NoAction) + osoc osoc @relation(fields: [osoc_id], references: [osoc_id], onDelete: NoAction, onUpdate: NoAction) + + @@unique([login_user_id, osoc_id]) +} + enum decision_enum { YES NO @@ -217,11 +227,12 @@ enum contract_status_enum { } enum email_status_enum { - SCHEDULED - SENT - FAILED - NONE - DRAFT + APPLIED + AWAITING_PROJECT @map("AWAITING PROJECT") + APPROVED + CONTRACT_CONFIRMED @map("CONTRACT CONFIRMED") + CONTRACT_DECLINED @map("CONTRACT DECLINED") + REJECTED } enum type_enum { diff --git a/backend/request.ts b/backend/request.ts index 8088eaa8..bdd7fe38 100644 --- a/backend/request.ts +++ b/backend/request.ts @@ -3,12 +3,15 @@ import express from "express"; import * as validator from "validator"; import * as config from "./config.json"; +import { FilterSort } from "./orm_functions/orm_types"; import { Anything, Decision, FollowupType, InternalTypes, Requests, + EmailStatus, + AccountStatus, } from "./types"; import { errors, getSessionKey } from "./utility"; @@ -37,6 +40,15 @@ const types: RequestTypes = { id: "Id", }; +/** + * Rejects a promise with an argument error. + * @template T The type the promise would resolve to. + * @returns A Promise rejecting with an Argument Error. + */ +function checkStringBoolean(value: string): boolean { + return value === "true" || value === "false"; +} + /** * Rejects a promise with an argument error. * @template T The type the promise would resolve to. @@ -57,13 +69,6 @@ function rejector(): Promise { function anyHasFields(obj: Anything, fields: string[]): boolean { for (const f of fields) { if (!(f in obj)) { - console.log( - "!!! Missing argument " + - f + - " in `" + - JSON.stringify(obj) + - "`!!!" - ); return false; } } @@ -99,9 +104,7 @@ function hasFields( return Promise.reject(errors.cookUnauthenticated()); } } - // if ((reqType == types.key || reqType == types.id) && - // (!("sessionkey" in req.body) || req.body.sessionkey == undefined)) - // return Promise.reject(errors.cookUnauthenticated()); + if (reqType == types.id && !("id" in req.params)) return rejector(); return anyHasFields(req.body, fields) ? Promise.resolve() : rejector(); } @@ -127,6 +130,38 @@ function maybe(obj: Anything, key: string): T | undefined { return key in obj ? (obj[key] as T) : undefined; } +/** + * Resolves with the given object if the `object.id` is a valid number + * (not NaN), otherwise, returns the rejector. + * @template T The type of object to validate (should be an IdRequest). + * @param r The object to validate. + * @return A promise resolving with the object if it's valid, otherwise one + * rejecting with an argument error. + */ +export function idIsNumber(r: T): Promise { + return isNaN(r.id) ? rejector() : Promise.resolve(r); +} + +/** + * Resolves with the given object if none of the keys is a NaN value (they can + * be undefined) in the given object; otherwise, returns the rejector. + * @template T The type of object to validate. + * @param keys The keys to check. + * @param obj The object to validate. + * @return A promise resolving with the object if it's valid, otherwise one + * rejecting with an argument error. + */ +export function allNonNaN( + keys: string[], + obj: T +): Promise { + return keys.every((v) => { + return obj[v] == undefined || !isNaN(obj[v] as number); + }) + ? Promise.resolve(obj) + : rejector(); +} + /** * Parses a key-only request. * @param req The request to check. @@ -143,6 +178,26 @@ async function parseKeyRequest( ); } +async function parsePaginationRequest( + req: express.Request +): Promise { + return parseKeyRequest(req).then((parsed) => { + let currentPage = 0; + let pageSize = config.global.pageSize; + if ("currentPage" in req.body) { + currentPage = Number(req.body.currentPage); + } + if ("pageSize" in req.body && !isNaN(Number(req.body.pageSize))) { + pageSize = Number(req.body.pageSize); + } + return { + ...parsed, + currentPage: currentPage, + pageSize: pageSize, + }; + }); +} + /** * Parses a request requiring both a key and an ID. * @param req The request to check. @@ -156,7 +211,7 @@ async function parseKeyIdRequest( Promise.resolve({ sessionkey: getSessionKey(req), id: Number(req.params.id), - }) + }).then(idIsNumber) ); } @@ -169,7 +224,7 @@ async function parseKeyIdRequest( async function parseUpdateLoginUser( req: express.Request ): Promise { - return hasFields(req, [], types.id).then(() => { + return hasFields(req, [], types.id).then(async () => { return Promise.resolve({ sessionkey: getSessionKey(req), id: Number(req.params.id), @@ -179,7 +234,7 @@ async function parseUpdateLoginUser( req.body, "accountStatus" ) as account_status_enum, - }); + }).then(idIsNumber); }); } @@ -215,8 +270,7 @@ export async function parseUpdateStudentRequest( ): Promise { const bodyF = [ "emailOrGithub", - "firstName", - "lastName", + "name", "gender", "pronouns", "phone", @@ -225,23 +279,28 @@ export async function parseUpdateStudentRequest( "education", ]; - return hasFields(req, [], types.id).then(() => { - if (!atLeastOneField(req, bodyF)) return rejector(); + return hasFields(req, [], types.id) + .then(() => { + if (!atLeastOneField(req, bodyF)) + return rejector(); - return Promise.resolve({ - sessionkey: getSessionKey(req), - id: Number(req.params.id), - emailOrGithub: maybe(req.body, "emailOrGithub"), - firstName: maybe(req.body, "firstName"), - lastName: maybe(req.body, "lastName"), - gender: maybe(req.body, "gender"), - pronouns: maybe(req.body, "pronouns"), - phone: maybe(req.body, "phone"), - education: maybe(req.body, "education"), - alumni: maybe(req.body, "alumni"), - nickname: maybe(req.body, "nickname"), - }); - }); + return Promise.resolve({ + sessionkey: getSessionKey(req), + id: Number(req.params.id), + emailOrGithub: maybe(req.body, "emailOrGithub"), + name: maybe(req.body, "name"), + gender: maybe(req.body, "gender"), + pronouns: maybe(req.body, "pronouns"), + phone: maybe(req.body, "phone"), + education: maybe( + req.body, + "education" + ), + alumni: maybe(req.body, "alumni"), + nickname: maybe(req.body, "nickname"), + }); + }) + .then(idIsNumber); } /** @@ -253,18 +312,25 @@ export async function parseUpdateStudentRequest( export async function parseSuggestStudentRequest( req: express.Request ): Promise { - return hasFields(req, ["suggestion"], types.id).then(() => { - const sug: unknown = req.body.suggestion; - if (sug != Decision.YES && sug != Decision.MAYBE && sug != Decision.NO) - return rejector(); + return hasFields(req, ["suggestion", "job_application_id"], types.id).then( + async () => { + const sug: unknown = req.body.suggestion; + if ( + sug != Decision.YES && + sug != Decision.MAYBE && + sug != Decision.NO + ) + return rejector(); - return Promise.resolve({ - sessionkey: getSessionKey(req), - id: Number(req.params.id), - suggestion: sug as InternalTypes.Suggestion, - reason: maybe(req.body, "reason"), - }); - }); + return Promise.resolve({ + sessionkey: getSessionKey(req), + id: Number(req.params.id), + suggestion: sug as InternalTypes.Suggestion, + job_application_id: req.body.job_application_id, + reason: maybe(req.body, "reason"), + }).then(idIsNumber); + } + ); } /** @@ -275,6 +341,31 @@ export async function parseSuggestStudentRequest( */ export async function parseGetSuggestionsStudentRequest( req: express.Request +): Promise { + return hasFields(req, [], types.id).then(async () => { + if ("year" in req.body) { + return Promise.resolve({ + sessionkey: getSessionKey(req), + id: Number(req.params.id), + year: Number(req.body.year), + }).then((o) => allNonNaN(["id", "year"], o)); + } else { + return Promise.resolve({ + sessionkey: getSessionKey(req), + id: Number(req.params.id), + }).then(idIsNumber); + } + }); +} + +/** + * Parses a request to `GET /student/`. + * @param req The request to check. + * @returns A Promise resolving to the parsed data or rejecting with an + * Argument or Unauthenticated error. + */ +export async function parseSingleStudentRequest( + req: express.Request ): Promise { return hasFields(req, [], types.id).then(() => { if ("year" in req.body) { @@ -301,9 +392,11 @@ export async function parseGetSuggestionsStudentRequest( export async function parseFilterOsocsRequest( req: express.Request ): Promise { - let year = maybe(req.body, "yearFilter"); + const authenticated = await parsePaginationRequest(req); // enforce authentication + let year = maybe(req.body, "yearFilter"); if ("yearFilter" in req.body) { - year = parseInt(req.body.yearFilter); + year = Number(req.body.yearFilter); + if (isNaN(year)) return rejector(); } for (const filter of [maybe(req.body, "yearSort")]) { @@ -313,9 +406,9 @@ export async function parseFilterOsocsRequest( } return Promise.resolve({ - sessionkey: getSessionKey(req), + ...authenticated, yearFilter: year, - yearSort: maybe(req.body, "yearSort"), + yearSort: maybe(req.body, "yearSort"), }); } @@ -328,13 +421,23 @@ export async function parseFilterOsocsRequest( export async function parseFilterStudentsRequest( req: express.Request ): Promise { - let mail = maybe(req.body, "emailFilter"); - let roles = maybe(req.body, "roleFilter"); + const paged = await parsePaginationRequest(req); // ensure authentication + + let mail = maybe(req.body, "emailFilter"); + let roles: string[] | undefined = undefined; // = maybe(req.body, "roleFilter"); if ( - "statusFilter" in req.body && - req.body.statusFilter !== Decision.YES && - req.body.statusFilter !== Decision.MAYBE && - req.body.statusFilter !== Decision.NO + ("statusFilter" in req.body && + !Object.values(Decision).includes( + req.body.statusFilter as unknown as Decision + )) || + ("emailStatusFilter" in req.body && + !Object.values(EmailStatus).includes( + req.body.emailStatusFilter as unknown as EmailStatus + )) || + ("alumniFilter" in req.body && + !checkStringBoolean(req.body.alumniFilter.toString())) || + ("coachFilter" in req.body && + !checkStringBoolean(req.body.coachFilter.toString())) ) { return rejector(); } else { @@ -351,49 +454,46 @@ export async function parseFilterStudentsRequest( } if ("roleFilter" in req.body) { - roles = req.body.roleFilter.split(","); + if (typeof req.body.roleFilter === "string") + roles = req.body.roleFilter.split(","); + else roles = req.body.roleFilter as string[]; } for (const filter of [ - maybe(req.body, "firstNameSort"), - maybe(req.body, "lastNameSort"), + maybe(req.body, "nameSort"), maybe(req.body, "emailSort"), - maybe(req.body, "roleSort"), - maybe(req.body, "alumniSort"), ]) { if (filter != undefined && filter !== "asc" && filter !== "desc") { return rejector(); } } - let osoc_year = new Date().getFullYear(); + let osoc_year; if ("osocYear" in req.body) { osoc_year = Number(req.body.osocYear); + if (isNaN(osoc_year)) return rejector(); } - let alumniFilter = maybe(req.body, "alumniFilter"); + let alumniFilter: boolean | undefined = undefined; if ("alumniFilter" in req.body) { - alumniFilter = Boolean(req.body.alumniFilter); + alumniFilter = req.body.alumniFilter.toString() === "true"; } - let coachFilter = maybe(req.body, "coachFilter"); + let coachFilter: boolean | undefined = undefined; if ("coachFilter" in req.body) { - coachFilter = Boolean(req.body.coachFilter); + coachFilter = req.body.coachFilter.toString() === "true"; } return Promise.resolve({ - sessionkey: getSessionKey(req), + ...paged, osocYear: osoc_year, - firstNameFilter: maybe(req.body, "firstNameFilter"), - lastNameFilter: maybe(req.body, "lastNameFilter"), + nameFilter: maybe(req.body, "nameFilter"), emailFilter: mail, roleFilter: roles, alumniFilter: alumniFilter, coachFilter: coachFilter, statusFilter: maybe(req.body, "statusFilter"), emailStatusFilter: maybe(req.body, "emailStatusFilter"), - firstNameSort: maybe(req.body, "firstNameSort"), - lastNameSort: maybe(req.body, "lastNameSort"), + nameSort: maybe(req.body, "nameSort"), emailSort: maybe(req.body, "emailSort"), - alumniSort: maybe(req.body, "alumniSort"), }); } @@ -406,20 +506,18 @@ export async function parseFilterStudentsRequest( export async function parseFilterUsersRequest( req: express.Request ): Promise { + const paginated = await parsePaginationRequest(req); // enforce authentication let mail = undefined; - let isCoachFilter = undefined; - if ("isCoachFilter" in req.body) { - isCoachFilter = req.body.isCoachFilter === "true"; - } - let isAdminFilter = undefined; - if ("isAdminFilter" in req.body) { - isAdminFilter = req.body.isAdminFilter === "true"; - } + if ( - "statusFilter" in req.body && - req.body.statusFilter !== "ACTIVATED" && - req.body.statusFilter !== "PENDING" && - req.body.statusFilter !== "DISABLED" + ("statusFilter" in req.body && + !Object.values(AccountStatus).includes( + req.body.statusFilter as unknown as AccountStatus + )) || + ("isCoachFilter" in req.body && + !checkStringBoolean(req.body.isCoachFilter.toString())) || + ("isAdminFilter" in req.body && + !checkStringBoolean(req.body.isAdminFilter.toString())) ) { return rejector(); } else { @@ -435,6 +533,15 @@ export async function parseFilterUsersRequest( } } + let isCoachFilter = undefined; + if ("isCoachFilter" in req.body) { + isCoachFilter = req.body.isCoachFilter.toString() === "true"; + } + let isAdminFilter = undefined; + if ("isAdminFilter" in req.body) { + isAdminFilter = req.body.isAdminFilter.toString() === "true"; + } + for (const filter of [ maybe(req.body, "nameSort"), maybe(req.body, "emailSort"), @@ -445,7 +552,7 @@ export async function parseFilterUsersRequest( } return Promise.resolve({ - sessionkey: getSessionKey(req), + ...paginated, nameFilter: maybe(req.body, "nameFilter"), emailFilter: mail, statusFilter: maybe(req.body, "statusFilter"), @@ -465,23 +572,25 @@ export async function parseFilterUsersRequest( export async function parseFinalizeDecisionRequest( req: express.Request ): Promise { - return hasFields(req, [], types.id).then(() => { - if ("reply" in req.body) { + return hasFields(req, ["reply", "job_application_id"], types.id).then( + async () => { if ( req.body.reply != Decision.YES && req.body.reply != Decision.MAYBE && req.body.reply != Decision.NO - ) + ) { return rejector(); - } + } - return Promise.resolve({ - sessionkey: getSessionKey(req), - id: Number(req.params.id), - reason: maybe(req.body, "reason"), - reply: maybe(req.body, "reply"), - }); - }); + return Promise.resolve({ + sessionkey: getSessionKey(req), + id: Number(req.params.id), + job_application_id: req.body.job_application_id, + reason: maybe(req.body, "reason"), + reply: req.body.reply, + }).then(idIsNumber); + } + ); } /** @@ -493,14 +602,12 @@ export async function parseFinalizeDecisionRequest( export async function parseRequestUserRequest( req: express.Request ): Promise { - return hasFields(req, ["firstName", "email", "pass"], types.neither).then( - () => - Promise.resolve({ - firstName: req.body.firstName, - lastName: "", - email: req.body.email, - pass: req.body.pass, - }) + return hasFields(req, ["name", "email", "pass"], types.neither).then(() => + Promise.resolve({ + name: req.body.name, + email: req.body.email, + pass: req.body.pass, + }) ); } @@ -515,7 +622,16 @@ export async function parseNewProjectRequest( ): Promise { return hasFields( req, - ["name", "partner", "start", "end", "positions", "osocId"], + [ + "name", + "partner", + "start", + "end", + "osocId", + "roles", + "description", + "coaches", + ], types.key ).then(() => Promise.resolve({ @@ -524,9 +640,11 @@ export async function parseNewProjectRequest( partner: req.body.partner, start: req.body.start, end: req.body.end, - osocId: req.body.osocId, - positions: req.body.positions, - }) + osocId: Number(req.body.osocId), + roles: req.body.roles, + description: req.body.description, + coaches: req.body.coaches, + }).then((o) => allNonNaN(["positions", "osocId"], o)) ); } @@ -539,20 +657,38 @@ export async function parseNewProjectRequest( export async function parseUpdateProjectRequest( req: express.Request ): Promise { - const options = ["name", "partner", "start", "end", "positions"]; + const options = [ + "name", + "partner", + "start", + "end", + "roles", + "description", + "addCoaches", + "removeCoaches", + ]; - return hasFields(req, [], types.id).then(() => { + return hasFields(req, [], types.id).then(async () => { if (!atLeastOneField(req, options)) return rejector(); return Promise.resolve({ sessionkey: getSessionKey(req), id: Number(req.params.id), - name: maybe(req.body, "name"), - partner: maybe(req.body, "partner"), - start: maybe(req.body, "start"), - end: maybe(req.body, "end"), - positions: maybe(req.body, "positions"), - }); + name: maybe(req.body, "name"), + partner: maybe(req.body, "partner"), + start: maybe(req.body, "start"), + end: maybe(req.body, "end"), + roles: maybe<{ roles: [{ name: string; positions: number }] }>( + req.body, + "roles" + ), + description: maybe(req.body, "description"), + addCoaches: maybe<{ coaches: [number] }>(req.body, "addCoaches"), + removeCoaches: maybe<{ coaches: [number] }>( + req.body, + "removeCoaches" + ), + }).then(idIsNumber); }); } @@ -565,43 +701,37 @@ export async function parseUpdateProjectRequest( export async function parseFilterProjectsRequest( req: express.Request ): Promise { + const paginated = await parsePaginationRequest(req); // enforce authentication for (const filter of [ maybe(req.body, "projectNameSort"), maybe(req.body, "clientNameSort"), - maybe(req.body, "fullyAssignedSort"), ]) { if (filter != undefined && filter !== "asc" && filter !== "desc") { return rejector(); } } - let assignedCoachesFilterArray = maybe( - req.body, - "assignedCoachesFilterArray" - ); - if ("assignedCoachesFilterArray" in req.body) { - if (typeof req.body.assignedCoachesFilterArray === "string") { - assignedCoachesFilterArray = req.body.assignedCoachesFilterArray - .slice(1, -1) - .split(",") - .map((num: string) => Number(num)); + let fullyAssignedFilter = maybe(req.body, "fullyAssignedFilter"); + if ("fullyAssignedFilter" in req.body) { + if (!checkStringBoolean(req.body.fullyAssignedFilter.toString())) { + return rejector(); } + fullyAssignedFilter = req.body.fullyAssignedFilter === "true"; } - let fullyAssignedFilter = maybe(req.body, "fullyAssignedFilter"); - if ("fullyAssignedFilter" in req.body) { - fullyAssignedFilter = req.body.fullyAssignedFilter === "true"; + let year; + if ("osocYear" in req.body && !isNaN(Number(req.body.osocYear))) { + year = parseInt(req.body.osocYear); } return Promise.resolve({ - sessionkey: getSessionKey(req), + ...paginated, projectNameFilter: maybe(req.body, "projectNameFilter"), clientNameFilter: maybe(req.body, "clientNameFilter"), - assignedCoachesFilterArray: assignedCoachesFilterArray, fullyAssignedFilter: fullyAssignedFilter, + osocYear: year, projectNameSort: maybe(req.body, "projectNameSort"), clientNameSort: maybe(req.body, "clientNameSort"), - fullyAssignedSort: maybe(req.body, "fullyAssignedSort"), }); } @@ -614,13 +744,18 @@ export async function parseFilterProjectsRequest( export async function parseDraftStudentRequest( req: express.Request ): Promise { - return hasFields(req, ["studentId", "role"], types.id).then(() => + return hasFields( + req, + ["studentId", "role", "jobApplicationId"], + types.id + ).then(() => Promise.resolve({ sessionkey: getSessionKey(req), id: Number(req.params.id), - studentId: req.body.studentId, + studentId: Number(req.body.studentId), + jobApplicationId: Number(req.body.jobApplicationId), role: req.body.role, - }) + }).then((o) => allNonNaN(["id", "studentId", "jobApplicationId"], o)) ); } @@ -633,14 +768,15 @@ export async function parseDraftStudentRequest( export async function parseSetFollowupStudentRequest( req: express.Request ): Promise { - return hasFields(req, ["type"], types.id).then(() => { + return hasFields(req, ["type"], types.id).then(async () => { const type: string = req.body.type; if ( - type != "SCHEDULED" && - type != "SENT" && - type != "FAILED" && - type != "NONE" && - type != "DRAFT" + type != "APPLIED" && + type != "AWAITING_PROJECT" && + type != "APPROVED" && + type != "CONTRACT_CONFIRMED" && + type != "CONTRACT_DECLINED" && + type != "REJECTED" ) return rejector(); @@ -648,7 +784,7 @@ export async function parseSetFollowupStudentRequest( sessionkey: getSessionKey(req), id: Number(req.params.id), type: type as FollowupType, - }); + }).then(idIsNumber); }); } @@ -681,18 +817,18 @@ export async function parseNewTemplateRequest( export async function parseUpdateTemplateRequest( req: express.Request ): Promise { - return hasFields(req, [], types.id).then(() => { + return hasFields(req, [], types.id).then(async () => { if (!atLeastOneField(req, ["name", "subject", "cc", "content"])) return rejector(); return Promise.resolve({ sessionkey: getSessionKey(req), id: Number(req.params.id), - name: maybe(req.body, "name"), - subject: maybe(req.body, "subject"), - cc: maybe(req.body, "cc"), - content: maybe(req.body, "content"), - }); + name: maybe(req.body, "name"), + subject: maybe(req.body, "subject"), + cc: maybe(req.body, "cc"), + content: maybe(req.body, "content"), + }).then(idIsNumber); }); } @@ -731,11 +867,17 @@ export async function parseFormRequest( export async function parseRequestResetRequest( req: express.Request ): Promise { - return hasFields(req, ["email"], types.neither).then(() => - Promise.resolve({ - email: validator.default.normalizeEmail(req.body.email).toString(), - }) - ); + return hasFields(req, ["email"], types.neither).then(() => { + if (validator.default.isEmail(req.body.email)) { + return Promise.resolve({ + email: validator.default + .normalizeEmail(req.body.email) + .toString(), + }); + } + + return Promise.reject(errors.cookArgumentError()); + }); } export async function parseCheckResetCodeRequest( @@ -766,7 +908,7 @@ export async function parseResetPasswordRequest( export async function parseStudentRoleRequest( req: express.Request ): Promise { - return hasFields(req, ["name"], types.neither).then(() => + return hasFields(req, ["name"], types.key).then(() => Promise.resolve({ sessionkey: getSessionKey(req), name: req.body.name, @@ -782,7 +924,31 @@ export async function parseRemoveAssigneeRequest( sessionkey: getSessionKey(req), studentId: req.body.student, id: Number(req.params.id), - }) + }).then(idIsNumber) + ); +} + +export async function parseRemoveCoachRequest( + req: express.Request +): Promise { + return hasFields(req, ["loginUserId"], types.id).then(() => + Promise.resolve({ + sessionkey: getSessionKey(req), + loginUserId: Number(req.body.loginUserId), + id: Number(req.params.id), + }).then(idIsNumber) + ); +} + +export async function parseAssignCoachRequest( + req: express.Request +): Promise { + return hasFields(req, ["loginUserId"], types.id).then(() => + Promise.resolve({ + sessionkey: getSessionKey(req), + loginUserId: Number(req.body.loginUserId), + id: Number(req.params.id), + }).then(idIsNumber) ); } @@ -828,7 +994,7 @@ export async function parseAcceptNewUserRequest( id: Number(req.params.id), is_admin: req.body.is_admin, is_coach: req.body.is_coach, - }) + }).then(idIsNumber) ); } @@ -839,20 +1005,53 @@ export async function parseNewOsocEditionRequest( Promise.resolve({ sessionkey: getSessionKey(req), year: parseInt(req.body.year), + }).then((obj) => allNonNaN(["year"], obj)) + ); +} + +/** + * Parses a request to `POST/DELETE /user/year/:id`. + * @param req The request to check. + * @returns A Promise resolving to the parsed data or rejecting with an + * Argument or Unauthenticated error. + */ +export async function parseUsersPermissionsRequest( + req: express.Request +): Promise { + return hasFields(req, ["osoc_id", "login_user_id"], types.id).then(() => + Promise.resolve({ + sessionkey: getSessionKey(req), + id: Number(req.params.id), + osoc_id: parseInt(req.body.osoc_id), + login_user_id: parseInt(req.body.login_user_id), }) + .then((obj) => allNonNaN(["osoc_id", "login_user_id"], obj)) + .then(idIsNumber) ); } /** - * A request to `DELETE /login/` only requires a session key - * {@link parseKeyRequest}. + * Parses a request to `GET /user/years`. + * @param req The request to check. + * @returns A Promise resolving to the parsed data or rejecting with an + * Argument or Unauthenticated error. */ -export const parseLogoutRequest = parseKeyRequest; +export async function parseGetUserPermissionsRequest( + req: express.Request +): Promise { + return hasFields(req, [], types.id).then(() => + Promise.resolve({ + sessionkey: getSessionKey(req), + id: Number(req.params.id), + }).then(idIsNumber) + ); +} + /** - * A request to `GET /student/all` only requires a session key + * A request to `DELETE /login/` only requires a session key * {@link parseKeyRequest}. */ -export const parseStudentAllRequest = parseKeyRequest; +export const parseLogoutRequest = parseKeyRequest; /** * A request to `GET /roles/all` only requires a session key * {@link parseKeyRequest}. @@ -873,16 +1072,6 @@ export const parseGetAllCoachRequestsRequest = parseKeyRequest; * {@link parseKeyRequest}. */ export const parseAdminAllRequest = parseKeyRequest; -/** - * A request to `GET /user/all` only requires a session key - * {@link parseKeyRequest}. - */ -export const parseUserAllRequest = parseKeyRequest; -/** - * A request to `GET /project/all` only requires a session key - * {@link parseKeyRequest}. - */ -export const parseProjectAllRequest = parseKeyRequest; /** * A request to `GET /project/conflicts` only requires a session key * {@link parseKeyRequest}. @@ -913,12 +1102,6 @@ export const parseCurrentUserRequest = parseKeyRequest; * {@link parseKeyRequest}. */ export const parseVerifyRequest = parseKeyRequest; - -/** - * A request to `GET /student/` only requires a session key and an ID - * {@link parseKeyIdRequest}. - */ -export const parseSingleStudentRequest = parseKeyIdRequest; /** * A request to `DELETE /student/` only requires a session key and an ID * {@link parseKeyIdRequest}. @@ -996,11 +1179,6 @@ export const parseUpdateCoachRequest = parseUpdateLoginUser; * {@link parseUpdateLoginUser}. */ export const parseUpdateAdminRequest = parseUpdateLoginUser; -/** - * A request to `GET /osoc/all` only requires a session key - * {@link parseKeyRequest}. - */ -export const parseOsocAllRequest = parseKeyRequest; /** * Parses a request to `POST /osoc/`. * @param req The request to check. @@ -1012,3 +1190,28 @@ export const parseOsocAllRequest = parseKeyRequest; * {@link parseKeyIdRequest}. */ export const parseDeleteOsocEditionRequest = parseKeyIdRequest; + +/** + * A request to `GET /user/all` only requires a session key and optionally the + * current page numer + * {@link parsePaginationRequest}. + */ +export const parseUserAllRequest = parsePaginationRequest; +/** + * A request to `GET /project/all` only requires a session key and optionally + * the current page numer + * {@link parsePaginationRequest}. + */ +export const parseProjectAllRequest = parsePaginationRequest; +/** + * A request to `GET /student/all` only requires a session key and optionally + * the current page numer + * {@link parsePaginationRequest}. + */ +export const parseStudentAllRequest = parsePaginationRequest; +/** + * A request to `GET /osoc/all` only requires a session key and optionally the + * current page number + * {@link parseKeyRequest}. + */ +export const parseOsocAllRequest = parsePaginationRequest; diff --git a/backend/routes/admin.ts b/backend/routes/admin.ts index 9fbd4e6b..b39dceab 100644 --- a/backend/routes/admin.ts +++ b/backend/routes/admin.ts @@ -2,13 +2,11 @@ import { account_status_enum } from "@prisma/client"; import express from "express"; import * as ormL from "../orm_functions/login_user"; -import * as ormP from "../orm_functions/person"; import * as ormSe from "../orm_functions/session_key"; import * as rq from "../request"; import { Responses } from "../types"; import * as util from "../utility"; import { errors } from "../utility"; -import { removeAllKeysForLoginUserId } from "../orm_functions/session_key"; /** * Attempts to list all admins in the system. @@ -29,10 +27,7 @@ export async function listAdmins( obj.map((val) => ({ person_data: { id: val.person.person_id, - name: - val.person.firstname + - " " + - val.person.lastname, + name: val.person.name, email: val.person.email, github: val.person.github, }, @@ -71,8 +66,6 @@ export async function modAdmin(req: express.Request): Promise { .accountStatus as account_status_enum, }) .then(async (res) => { - console.log(res.is_admin); - console.log(res.is_coach); if (!res.is_admin && !res.is_coach) { await ormL.updateLoginUser({ loginUserId: res.login_user_id, @@ -86,10 +79,7 @@ export async function modAdmin(req: express.Request): Promise { } return Promise.resolve({ id: res.login_user_id, - name: - res.person.firstname + - " " + - res.person.lastname, + name: res.person.name, }); }); } @@ -111,40 +101,17 @@ export async function deleteAdmin( .then((parsed) => util.isAdmin(parsed)) .then((parsed) => util.mutable(parsed, parsed.data.id)) .then(async (parsed) => { - return ormL - .searchLoginUserByPerson(parsed.data.id) - .then((logUs) => { - if ( - logUs !== null && - logUs.login_user_id !== parsed.userId - ) { - return removeAllKeysForLoginUserId(logUs.login_user_id) - .then(() => { - return Promise.resolve({}); - }) - .then(() => { - return ormL - .deleteLoginUserByPersonId(parsed.data.id) - .then(() => { - return ormP - .deletePersonById(parsed.data.id) - .then(() => Promise.resolve({})) - .catch(() => - Promise.reject( - errors.cookServerError() - ) - ); - }) - .catch(() => - Promise.reject(errors.cookServerError()) - ); - }) - .catch(() => - Promise.reject(errors.cookServerError()) - ); - } - return Promise.reject(errors.cookInvalidID()); - }); + // only try to delete the loginUser IF the userId exists and if we are not trying to delete ourselves + if ( + parsed.data.id !== null && + parsed.data.id !== undefined && + parsed.data.id !== parsed.userId + ) { + return ormL + .deleteLoginUserFromDB(parsed.data.id) + .then(() => Promise.resolve({})); + } + return Promise.reject(errors.cookInvalidID()); }); } diff --git a/backend/routes/coach.ts b/backend/routes/coach.ts index 3bf0d3f1..6109cfe3 100644 --- a/backend/routes/coach.ts +++ b/backend/routes/coach.ts @@ -2,14 +2,12 @@ import { account_status_enum } from "@prisma/client"; import express from "express"; import * as ormLU from "../orm_functions/login_user"; -import * as ormP from "../orm_functions/person"; import * as rq from "../request"; import { Responses } from "../types"; import * as util from "../utility"; import * as ormSe from "../orm_functions/session_key"; import { errors } from "../utility"; -import * as ormL from "../orm_functions/login_user"; -import { removeAllKeysForLoginUserId } from "../orm_functions/session_key"; +import { getLoginUserById } from "../orm_functions/login_user"; /** * Attempts to list all coaches in the system. @@ -30,13 +28,14 @@ export async function listCoaches( obj.map((val) => ({ person_data: { id: val.person.person_id, - name: val.person.firstname, + name: val.person.name, email: val.person.email, github: val.person.github, }, coach: val.is_coach, admin: val.is_admin, activated: val.account_status as string, + login_user_id: val.login_user_id, })) ) .then((obj) => @@ -62,20 +61,40 @@ export async function modCoach( .then((parsed) => util.mutable(parsed, parsed.data.id)) .then(async (parsed) => { if (parsed.data.id !== parsed.userId) { + // parse to enum + const accountStatus = parsed.data + .accountStatus as account_status_enum; + + // get the loginUser we are modifying. We need this user to check if the user is disabled at the moment or not + const userToModify = await getLoginUserById(parsed.data.id); + + // when we set the account to active and the account was disabled and isAdmin is not set to true => set isCoach to true. Otherwise just use the value from the request + const coachVal = + accountStatus === account_status_enum.ACTIVATED && + userToModify && + userToModify.account_status === + account_status_enum.DISABLED && + !parsed.data.isAdmin + ? true + : parsed.data.isCoach; + return ormLU .updateLoginUser({ loginUserId: parsed.data.id, isAdmin: parsed.data.isAdmin, - isCoach: parsed.data.isCoach, - accountStatus: parsed.data - .accountStatus as account_status_enum, + isCoach: coachVal, + accountStatus: accountStatus, }) .then(async (res) => { - if (!res.is_admin && !res.is_coach) { + if ( + !res.is_admin && + !res.is_coach && + accountStatus !== account_status_enum.ACTIVATED + ) { await ormSe.removeAllKeysForLoginUserId( res.login_user_id ); - await ormL.updateLoginUser({ + await ormLU.updateLoginUser({ loginUserId: res.login_user_id, isAdmin: false, isCoach: false, @@ -84,10 +103,7 @@ export async function modCoach( } return Promise.resolve({ id: res.login_user_id, - name: - res.person.firstname + - " " + - res.person.lastname, + name: res.person.name, }); }); } else { @@ -110,78 +126,9 @@ export async function deleteCoach( .then((parsed) => util.isAdmin(parsed)) .then((parsed) => util.mutable(parsed, parsed.data.id)) .then(async (parsed) => { - return ormL - .searchLoginUserByPerson(parsed.data.id) - .then((logUs) => { - if ( - logUs !== null && - logUs.login_user_id !== parsed.userId - ) { - return removeAllKeysForLoginUserId(logUs.login_user_id) - .then(() => { - return Promise.resolve({}); - }) - .then(() => { - return ormL - .deleteLoginUserByPersonId(parsed.data.id) - .then(() => { - return ormP - .deletePersonById(parsed.data.id) - .then(() => Promise.resolve({})) - .catch(() => - Promise.reject( - errors.cookServerError() - ) - ); - }) - .catch(() => - Promise.reject(errors.cookServerError()) - ); - }) - .catch(() => - Promise.reject(errors.cookServerError()) - ); - } - return Promise.reject(errors.cookInvalidID()); - }); - }); -} - -/** - * Attempts to get all data for the requests of coaches in the system. - * @param req The Express.js request to extract all required data from. - * @returns See the API documentation. Successes are passed using - * `Promise.resolve`, failures using `Promise.reject`. - */ -export async function getCoachRequests( - req: express.Request -): Promise { - return rq - .parseGetAllCoachRequestsRequest(req) - .then((parsed) => util.isAdmin(parsed)) - .then(async () => { return ormLU - .getAllLoginUsers() - .then((obj) => - obj - .filter( - (v) => v.is_coach && v.account_status == "PENDING" - ) - .map((v) => ({ - person_data: { - id: v.person.person_id, - name: v.person.firstname, - }, - coach: v.is_coach, - admin: v.is_admin, - activated: v.account_status as string, - })) - ) - .then((arr) => - Promise.resolve({ - data: arr, - }) - ); + .deleteLoginUserFromDB(parsed.data.id) + .then(() => Promise.resolve({})); }); } @@ -195,8 +142,6 @@ export function getRouter(): express.Router { util.setupRedirect(router, "/coach"); util.route(router, "get", "/all", listCoaches); - util.route(router, "get", "/request", getCoachRequests); - util.route(router, "post", "/:id", modCoach); util.route(router, "delete", "/:id", deleteCoach); diff --git a/backend/routes/followup.ts b/backend/routes/followup.ts index 56079d50..72a0f101 100644 --- a/backend/routes/followup.ts +++ b/backend/routes/followup.ts @@ -1,45 +1,13 @@ import express from "express"; import * as ormJA from "../orm_functions/job_application"; -import * as ormOsoc from "../orm_functions/osoc"; import * as rq from "../request"; import { Responses } from "../types"; import * as util from "../utility"; - -/** - * Attempts to list all followups in the system. - * @param req The Express.js request to extract all required data from. - * @returns See the API documentation. Successes are passed using - * `Promise.resolve`, failures using `Promise.reject`. - */ -export async function listFollowups( - req: express.Request -): Promise { - return rq - .parseFollowupAllRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) - .then(() => - ormOsoc - .getLatestOsoc() - .then((osoc) => util.getOrReject(osoc)) - .then(async (osoc) => - ormJA - .getJobApplicationByYear(osoc.year) - .then((arr) => - arr.map((v) => ({ - student: v.student_id, - application: v.job_application_id, - status: v.email_status, - })) - ) - .then((res) => - Promise.resolve({ - data: res, - }) - ) - ) - ); -} +import { checkYearPermissionStudent, errors } from "../utility"; +import { getOsocYearsForLoginUser } from "../orm_functions/login_user"; +import { getLatestOsoc, getOsocById } from "../orm_functions/osoc"; +import { getJobApplication } from "../orm_functions/job_application"; /** * Attempts to get a single followup. @@ -55,8 +23,20 @@ export async function getFollowup( .then((parsed) => util.checkSessionKey(parsed)) .then((checked) => ormJA - .getLatestJobApplicationOfStudent(checked.data.id) + .getJobApplication(checked.data.id) .then((data) => util.getOrReject(data)) + .then(async (data) => { + // check if this last year is visible for the loginUser + const visibleYears = await getOsocYearsForLoginUser( + checked.userId + ); + const osoc = await getOsocById(data.osoc_id); + + if (osoc !== null && visibleYears.includes(osoc.year)) { + return data; + } + return Promise.reject(errors.cookInsufficientRights()); + }) .then((ja) => Promise.resolve({ student: ja.student_id, @@ -78,10 +58,25 @@ export async function updateFollowup( ): Promise { return rq .parseSetFollowupStudentRequest(req) - .then((parsed) => util.isAdmin(parsed)) - .then((checked) => - ormJA - .getLatestJobApplicationOfStudent(checked.data.id) + .then((parsed) => util.checkSessionKey(parsed)) + .then(checkYearPermissionStudent) + .then(async (checked) => { + // modifications to a job application is only allowed if the job application is of the most recent osoc year + const [jobApplication, latestOsoc] = await Promise.all([ + getJobApplication(checked.data.id), + getLatestOsoc(), + ]); + + if (jobApplication === null || latestOsoc === null) { + return Promise.reject(errors.cookInvalidID()); + } + + if (jobApplication.osoc.year !== latestOsoc.year) { + return Promise.reject(errors.cookWrongOsocYear()); + } + + // do the modifications itself + return Promise.resolve(jobApplication) .then((ja) => util.getOrReject(ja)) .then((ja) => ormJA.changeEmailStatusOfJobApplication( @@ -95,15 +90,14 @@ export async function updateFollowup( application: res.job_application_id, status: res.email_status, }) - ) - ); + ); + }); } export function getRouter() { const router: express.Router = express.Router(); util.setupRedirect(router, "/followup"); - util.route(router, "get", "/all", listFollowups); util.route(router, "get", "/:id", getFollowup); util.route(router, "post", "/:id", updateFollowup); diff --git a/backend/routes/form.ts b/backend/routes/form.ts index 933a4c3d..b3b3cc70 100644 --- a/backend/routes/form.ts +++ b/backend/routes/form.ts @@ -2,6 +2,7 @@ import express from "express"; import * as ormP from "../orm_functions/person"; +import * as ormLU from "../orm_functions/login_user"; import * as ormSt from "../orm_functions/student"; import * as ormOs from "../orm_functions/osoc"; import * as ormJo from "../orm_functions/job_application"; @@ -17,6 +18,9 @@ import { type_enum } from "@prisma/client"; import * as validator from "validator"; import * as rq from "../request"; import * as config from "./form_keys.json"; +import * as T from "../types"; +import fs from "fs"; +import path from "path"; /** * This function searches a question with a given key in the form. @@ -80,7 +84,7 @@ export function checkQuestionsExist( questions: Responses.FormResponse[] ): boolean { const checkErrorInForm: Responses.FormResponse[] = - questions.filter((dataError) => dataError.data == null); + questions.filter((dataError) => dataError.data === null); return checkErrorInForm.length === 0; } @@ -97,11 +101,16 @@ export function getBirthName(form: Requests.Form): Promise { const questionBirthName: Responses.FormResponse = filterQuestion(form, config.birthName); const questionsExist: boolean = checkQuestionsExist([questionBirthName]); - if (!questionsExist || questionBirthName.data?.value == null) { + if ( + !questionsExist || + (questionBirthName.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } - return Promise.resolve(questionBirthName.data.value as string); + return Promise.resolve( + (questionBirthName.data as Requests.Question).value as string + ); } /** @@ -114,11 +123,16 @@ export function getLastName(form: Requests.Form): Promise { const questionLastName: Responses.FormResponse = filterQuestion(form, config.lastName); const questionsExist: boolean = checkQuestionsExist([questionLastName]); - if (!questionsExist || questionLastName.data?.value == null) { + if ( + !questionsExist || + (questionLastName.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } - return Promise.resolve(questionLastName.data.value as string); + return Promise.resolve( + (questionLastName.data as Requests.Question).value as string + ); } /** @@ -127,21 +141,42 @@ export function getLastName(form: Requests.Form): Promise { * @returns See the API documentation. Successes are passed using * `Promise.resolve`, failures using `Promise.reject`. */ -export function getEmail(form: Requests.Form): Promise { +export async function getEmail(form: Requests.Form): Promise { const questionEmail: Responses.FormResponse = filterQuestion(form, config.emailAddress); const questionsExist: boolean = checkQuestionsExist([questionEmail]); if ( !questionsExist || - questionEmail.data?.value == null || - !validator.default.isEmail(questionEmail.data.value as string) + (questionEmail.data as Requests.Question).value == null || + !validator.default.isEmail( + (questionEmail.data as Requests.Question).value as string + ) ) { return Promise.reject(errors.cookArgumentError()); } + const normalizedEmail = validator.default + .normalizeEmail( + (questionEmail.data as Requests.Question).value as string + ) + .toString(); + + const personFound = await ormP.searchPersonByLogin(normalizedEmail); + if (personFound.length !== 0) { + const loginUserFound = await ormLU.searchLoginUserByPerson( + personFound[0].person_id + ); + + if (loginUserFound !== null) { + return Promise.reject(errors.cookInsufficientRights()); + } + } + return Promise.resolve( validator.default - .normalizeEmail(questionEmail.data.value as string) + .normalizeEmail( + (questionEmail.data as Requests.Question).value as string + ) .toString() ); } @@ -160,8 +195,7 @@ export async function jsonToPerson( const email = await getEmail(form); return Promise.resolve({ - birthName: birthName, - lastName: lastName, + name: (birthName + " " + lastName).trim(), email: email, }); } @@ -188,14 +222,17 @@ export function getPronouns(form: Requests.Form): Promise { questionPreferredPronouns, questionEnterPronouns, ]); - if (!questionsExist || questionPronouns.data?.value == null) { + if ( + !questionsExist || + (questionPronouns.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } let pronouns = ""; const wordInAnswer: Responses.FormResponse = checkWordInAnswer( - questionPronouns.data, + questionPronouns.data as Requests.Question, "yes" ); @@ -210,22 +247,31 @@ export function getPronouns(form: Requests.Form): Promise { ); if ( chosenOption.data == null || - chosenOption.data?.id.length === 0 || - questionPreferredPronouns.data?.value == null || - checkWordInAnswer(questionPreferredPronouns.data, "other").data == - null + (chosenOption.data as Requests.Option).id.length === 0 || + (questionPreferredPronouns.data as Requests.Question).value == + null || + checkWordInAnswer( + questionPreferredPronouns.data as Requests.Question, + "other" + ).data == null ) { return Promise.reject(util.errors.cookArgumentError()); } else if ( - !checkWordInAnswer(questionPreferredPronouns.data, "other").data && - chosenOption.data?.text != undefined + !checkWordInAnswer( + questionPreferredPronouns.data as Requests.Question, + "other" + ).data && + (chosenOption.data as Requests.Option).text != undefined ) { pronouns = chosenOption.data.text; } else { - if (questionEnterPronouns.data?.value == null) { + if ( + (questionEnterPronouns.data as Requests.Question).value == null + ) { return Promise.resolve(null); } - pronouns = questionEnterPronouns.data.value as string; + pronouns = (questionEnterPronouns.data as Requests.Question) + .value as string; } } @@ -242,12 +288,15 @@ export function getGender(form: Requests.Form): Promise { const questionGender: Responses.FormResponse = filterQuestion(form, config.gender); const questionsExist: boolean = checkQuestionsExist([questionGender]); - if (!questionsExist || questionGender.data?.value == null) { + if ( + !questionsExist || + (questionGender.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } const chosenGender: Responses.FormResponse = - filterChosenOption(questionGender.data); + filterChosenOption(questionGender.data as Requests.Question); if (chosenGender.data == null || chosenGender.data.id.length === 0) { return Promise.reject(errors.cookArgumentError()); @@ -266,11 +315,16 @@ export function getPhoneNumber(form: Requests.Form): Promise { const questionPhoneNumber: Responses.FormResponse = filterQuestion(form, config.phoneNumber); const questionsExist: boolean = checkQuestionsExist([questionPhoneNumber]); - if (!questionsExist || questionPhoneNumber.data?.value == null) { + if ( + !questionsExist || + (questionPhoneNumber.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } - return Promise.resolve(questionPhoneNumber.data.value as string); + return Promise.resolve( + (questionPhoneNumber.data as Requests.Question).value as string + ); } /** @@ -289,17 +343,24 @@ export function getNickname(form: Requests.Form): Promise { questionCheckNickname, questionEnterNickname, ]); - if (!questionsExist || questionCheckNickname.data?.value == null) { + if ( + !questionsExist || + (questionCheckNickname.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } let nickname = null; - const addNickName = checkWordInAnswer(questionCheckNickname.data, "yes"); + const addNickName = checkWordInAnswer( + questionCheckNickname.data as Requests.Question, + "yes" + ); if (addNickName.data != null && addNickName.data) { - if (questionEnterNickname.data?.value == null) { + if ((questionEnterNickname.data as Requests.Question).value == null) { return Promise.reject(errors.cookArgumentError()); } - nickname = questionEnterNickname.data.value as string; + nickname = (questionEnterNickname.data as Requests.Question) + .value as string; } return Promise.resolve(nickname); @@ -317,12 +378,15 @@ export function getAlumni(form: Requests.Form): Promise { const questionsExist: boolean = checkQuestionsExist([questionCheckAlumni]); - if (!questionsExist || questionCheckAlumni.data?.value == null) { + if ( + !questionsExist || + (questionCheckAlumni.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } const wordInAnswer: boolean | null = checkWordInAnswer( - questionCheckAlumni.data, + questionCheckAlumni.data as Requests.Question, "yes" ).data; @@ -380,11 +444,17 @@ export function getResponsibilities( return Promise.reject(errors.cookArgumentError()); } - if (questionCheckResponsibilities.data?.value == undefined) { + if ( + (questionCheckResponsibilities.data as Requests.Question).value == + undefined + ) { return Promise.resolve(null); } - return Promise.resolve(questionCheckResponsibilities.data?.value as string); + return Promise.resolve( + (questionCheckResponsibilities.data as Requests.Question) + .value as string + ); } /** @@ -399,11 +469,16 @@ export function getFunFact(form: Requests.Form): Promise { const questionsExist: boolean = checkQuestionsExist([questionFunFact]); - if (!questionsExist || questionFunFact.data?.value == null) { + if ( + !questionsExist || + (questionFunFact.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } - return Promise.resolve(questionFunFact.data.value as string); + return Promise.resolve( + (questionFunFact.data as Requests.Question).value as string + ); } /** @@ -420,12 +495,17 @@ export function getVolunteerInfo(form: Requests.Form): Promise { questionCheckVolunteerInfo, ]); - if (!questionsExist || questionCheckVolunteerInfo.data?.value == null) { + if ( + !questionsExist || + (questionCheckVolunteerInfo.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } const chosenVolunteerInfo: Responses.FormResponse = - filterChosenOption(questionCheckVolunteerInfo.data); + filterChosenOption( + questionCheckVolunteerInfo.data as Requests.Question + ); if ( chosenVolunteerInfo.data == null || @@ -456,12 +536,15 @@ export function isStudentCoach( questionStudentCoach, ]); - if (!questionsExist || questionStudentCoach.data?.value == null) { + if ( + !questionsExist || + (questionStudentCoach.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } const wordInAnswer: boolean | null = checkWordInAnswer( - questionStudentCoach.data, + questionStudentCoach.data as Requests.Question, "yes" ).data; @@ -490,22 +573,29 @@ export function getEducations(form: Requests.Form): Promise { if ( !questionsExist || - questionCheckEducations.data?.value == null || - (questionCheckEducations.data.value as string[]).length === 0 || - (questionCheckEducations.data.value as string[]).length > 2 + (questionCheckEducations.data as Requests.Question).value == null || + ((questionCheckEducations.data as Requests.Question).value as string[]) + .length === 0 || + ((questionCheckEducations.data as Requests.Question).value as string[]) + .length > 2 ) { return Promise.reject(errors.cookArgumentError()); } const educations: string[] = []; - const questionValue = questionCheckEducations.data.value as string[]; + const questionValue = (questionCheckEducations.data as Requests.Question) + .value as string[]; for (let i = 0; i < questionValue.length; i++) { - if (questionCheckEducations.data.options != undefined) { - const filteredOption = questionCheckEducations.data.options.filter( - (option) => option.id === questionValue?.[i] - ); + if ( + (questionCheckEducations.data as Requests.Question).options != + undefined + ) { + const filteredOption = ( + (questionCheckEducations.data as Requests.Question) + .options as Requests.Option[] + ).filter((option) => option.id === questionValue[i]); if (filteredOption.length !== 1) { return Promise.reject(errors.cookArgumentError()); } @@ -518,12 +608,15 @@ export function getEducations(form: Requests.Form): Promise { if ( !questionsExistOther || - questionCheckOther.data?.value == null + (questionCheckOther.data as Requests.Question).value == null ) { return Promise.reject(errors.cookArgumentError()); } - educations.push(questionCheckOther.data.value as string); + educations.push( + (questionCheckOther.data as Requests.Question) + .value as string + ); } else { educations.push(filteredOption[0].text); } @@ -549,21 +642,29 @@ export function getEducationLevel(form: Requests.Form): Promise { if ( !questionsExist || - questionCheckEducationLevel.data?.value == null || - (questionCheckEducationLevel.data.value as string[]).length !== 1 + (questionCheckEducationLevel.data as Requests.Question).value == null || + ( + (questionCheckEducationLevel.data as Requests.Question) + .value as string[] + ).length !== 1 ) { return Promise.reject(errors.cookArgumentError()); } let educationLevel; - const educationLevelValue = questionCheckEducationLevel.data - ?.value as string[]; + const educationLevelValue = ( + questionCheckEducationLevel.data as Requests.Question + ).value as string[]; - if (questionCheckEducationLevel.data.options != undefined) { - const filteredOption = questionCheckEducationLevel.data.options.filter( - (option) => option.id === educationLevelValue?.[0] - ); + if ( + (questionCheckEducationLevel.data as Requests.Question).options != + undefined + ) { + const filteredOption = ( + (questionCheckEducationLevel.data as Requests.Question) + .options as Requests.Option[] + ).filter((option) => option.id === educationLevelValue[0]); if (filteredOption.length !== 1) { return Promise.reject(errors.cookArgumentError()); } @@ -576,12 +677,13 @@ export function getEducationLevel(form: Requests.Form): Promise { if ( !questionsExistOther || - questionCheckOther.data?.value == null + (questionCheckOther.data as Requests.Question).value == null ) { return Promise.reject(errors.cookArgumentError()); } - educationLevel = questionCheckOther.data.value as string; + educationLevel = (questionCheckOther.data as Requests.Question) + .value as string; } else { educationLevel = filteredOption[0].text; } @@ -612,11 +714,13 @@ export function getEducationDuration( return Promise.reject(errors.cookArgumentError()); } - if (questionEducationDuration.data?.value == null) { + if ((questionEducationDuration.data as Requests.Question).value == null) { return Promise.resolve(null); } - return Promise.resolve(Number(questionEducationDuration.data?.value)); + return Promise.resolve( + Number((questionEducationDuration.data as Requests.Question).value) + ); } /** @@ -637,11 +741,13 @@ export function getEducationYear(form: Requests.Form): Promise { return Promise.reject(errors.cookArgumentError()); } - if (questionEducationYear.data?.value == null) { + if ((questionEducationYear.data as Requests.Question).value == null) { return Promise.resolve(null); } - return Promise.resolve(questionEducationYear.data.value as string); + return Promise.resolve( + (questionEducationYear.data as Requests.Question).value as string + ); } /** @@ -664,11 +770,13 @@ export function getEducationUniversity( return Promise.reject(errors.cookArgumentError()); } - if (questionEducationUniversity.data?.value == null) { + if ((questionEducationUniversity.data as Requests.Question).value == null) { return Promise.resolve(null); } - return Promise.resolve(questionEducationUniversity.data.value as string); + return Promise.resolve( + (questionEducationUniversity.data as Requests.Question).value as string + ); } /** @@ -696,7 +804,7 @@ export async function jsonToJobApplication( const educationDuration = await getEducationDuration(form); const educationYear = await getEducationYear(form); const educationInstitute = await getEducationUniversity(form); - const emailStatus = "NONE"; + const emailStatus = "APPLIED"; let createdAt = new Date(Date.now()).toString(); if (form.createdAt != undefined) { createdAt = form.createdAt; @@ -735,12 +843,17 @@ export function getMostFluentLanguage(form: Requests.Form): Promise { questionMostFluentLanguage, ]); - if (!questionsExist || questionMostFluentLanguage.data?.value == null) { + if ( + !questionsExist || + (questionMostFluentLanguage.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } const chosenLanguage: Responses.FormResponse = - filterChosenOption(questionMostFluentLanguage.data); + filterChosenOption( + questionMostFluentLanguage.data as Requests.Question + ); if (chosenLanguage.data == null) { return Promise.reject(errors.cookArgumentError()); @@ -755,11 +868,15 @@ export function getMostFluentLanguage(form: Requests.Form): Promise { questionCheckOther, ]); - if (!questionsExistOther || questionCheckOther.data?.value == null) { + if ( + !questionsExistOther || + (questionCheckOther.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } - language = questionCheckOther.data.value as string; + language = (questionCheckOther.data as Requests.Question) + .value as string; } else { language = chosenLanguage.data.text; } @@ -779,12 +896,15 @@ export function getEnglishLevel(form: Requests.Form): Promise { const questionsExist: boolean = checkQuestionsExist([questionEnglishLevel]); - if (!questionsExist || questionEnglishLevel.data?.value == null) { + if ( + !questionsExist || + (questionEnglishLevel.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } const chosenLanguage: Responses.FormResponse = - filterChosenOption(questionEnglishLevel.data); + filterChosenOption(questionEnglishLevel.data as Requests.Question); if (chosenLanguage.data == null) { return Promise.reject(errors.cookArgumentError()); @@ -815,11 +935,16 @@ export function getBestSkill(form: Requests.Form): Promise { const questionsExist: boolean = checkQuestionsExist([questionBestSkill]); - if (!questionsExist || questionBestSkill.data?.value == null) { + if ( + !questionsExist || + (questionBestSkill.data as Requests.Question).value == null + ) { return Promise.reject(errors.cookArgumentError()); } - return Promise.resolve(questionBestSkill.data.value as string); + return Promise.resolve( + (questionBestSkill.data as Requests.Question).value as string + ); } /** @@ -871,22 +996,29 @@ export function getCV( return Promise.reject(errors.cookArgumentError()); } if ( - questionCVUpload.data?.value == null && - questionCVLink.data?.value == null + (questionCVUpload.data as Requests.Question).value == null && + (questionCVLink.data as Requests.Question).value == null ) { return Promise.resolve({ data: [], types: [] }); } - if (questionCVLink.data?.value != null) { - if ((questionCVLink.data?.value as string).trim() != "") { - links.push(questionCVLink.data?.value as string); + if ((questionCVLink.data as Requests.Question).value != null) { + if ( + ( + (questionCVLink.data as Requests.Question).value as string + ).trim() != "" + ) { + links.push( + (questionCVLink.data as Requests.Question).value as string + ); types.push("CV_URL"); } } - const cvUploadValue = questionCVUpload.data?.value as Requests.FormValues[]; + const cvUploadValue = (questionCVUpload.data as Requests.Question) + .value as Requests.FormValues[]; - if (questionCVUpload.data?.value != null) { + if ((questionCVUpload.data as Requests.Question).value != null) { for (let linkIndex = 0; linkIndex < cvUploadValue.length; linkIndex++) { if ( (cvUploadValue[linkIndex] as Requests.FormValues).url == @@ -937,23 +1069,32 @@ export function getPortfolio( } if ( - questionPortfolioUpload.data?.value == null && - questionPortfolioLink.data?.value == null + (questionPortfolioUpload.data as Requests.Question).value == null && + (questionPortfolioLink.data as Requests.Question).value == null ) { return Promise.resolve({ data: [], types: [] }); } - if (questionPortfolioLink.data?.value != null) { - if ((questionPortfolioLink.data?.value as string).trim() != "") { - links.push(questionPortfolioLink.data?.value as string); + if ((questionPortfolioLink.data as Requests.Question).value != null) { + if ( + ( + (questionPortfolioLink.data as Requests.Question) + .value as string + ).trim() != "" + ) { + links.push( + (questionPortfolioLink.data as Requests.Question) + .value as string + ); types.push("PORTFOLIO_URL"); } } - const portfolioUploadValue = questionPortfolioUpload.data - ?.value as Requests.FormValues[]; + const portfolioUploadValue = ( + questionPortfolioUpload.data as Requests.Question + ).value as Requests.FormValues[]; - if (questionPortfolioUpload.data?.value != null) { + if ((questionPortfolioUpload.data as Requests.Question).value != null) { for ( let linkIndex = 0; linkIndex < portfolioUploadValue.length; @@ -1012,24 +1153,33 @@ export function getMotivation( } if ( - questionMotivationUpload.data?.value == null && - questionMotivationLink.data?.value == null && - questionMotivationString.data?.value == null + (questionMotivationUpload.data as Requests.Question).value == null && + (questionMotivationLink.data as Requests.Question).value == null && + (questionMotivationString.data as Requests.Question).value == null ) { return Promise.resolve({ data: [], types: [] }); } - if (questionMotivationLink.data?.value != null) { - if ((questionMotivationLink.data?.value as string).trim() != "") { - data.push(questionMotivationLink.data?.value as string); + if ((questionMotivationLink.data as Requests.Question).value != null) { + if ( + ( + (questionMotivationLink.data as Requests.Question) + .value as string + ).trim() != "" + ) { + data.push( + (questionMotivationLink.data as Requests.Question) + .value as string + ); types.push("MOTIVATION_URL"); } } - const motivationUploadValue = questionMotivationUpload.data - ?.value as Requests.FormValues[]; + const motivationUploadValue = ( + questionMotivationUpload.data as Requests.Question + ).value as Requests.FormValues[]; - if (questionMotivationUpload.data?.value != null) { + if ((questionMotivationUpload.data as Requests.Question).value != null) { for ( let linkIndex = 0; linkIndex < motivationUploadValue.length; @@ -1056,10 +1206,18 @@ export function getMotivation( } } - if (questionMotivationString.data?.value != null) { - if ((questionMotivationString.data?.value as string).trim() != "") { - data.push(questionMotivationString.data?.value as string); - types.push("MOTIVATION_URL"); + if ((questionMotivationString.data as Requests.Question).value != null) { + if ( + ( + (questionMotivationString.data as Requests.Question) + .value as string + ).trim() != "" + ) { + data.push( + (questionMotivationString.data as Requests.Question) + .value as string + ); + types.push("MOTIVATION_STRING"); } } @@ -1103,22 +1261,29 @@ export function getAppliedRoles(form: Requests.Form): Promise { if ( !questionsExist || - questionAppliedRoles.data?.value == null || - (questionAppliedRoles.data.value as string[]).length === 0 || - (questionAppliedRoles.data.value as string[]).length > 2 + (questionAppliedRoles.data as Requests.Question).value == null || + ((questionAppliedRoles.data as Requests.Question).value as string[]) + .length === 0 || + ((questionAppliedRoles.data as Requests.Question).value as string[]) + .length > 2 ) { return Promise.reject(errors.cookArgumentError()); } - const appliedRolesValue = questionAppliedRoles.data?.value as string[]; + const appliedRolesValue = (questionAppliedRoles.data as Requests.Question) + .value as string[]; const appliedRoles: string[] = []; for (let i = 0; i < appliedRolesValue.length; i++) { - if (questionAppliedRoles.data.options != undefined) { - const filteredOption = questionAppliedRoles.data.options.filter( - (option) => option.id === appliedRolesValue?.[i] - ); + if ( + (questionAppliedRoles.data as Requests.Question).options != + undefined + ) { + const filteredOption = ( + (questionAppliedRoles.data as Requests.Question) + .options as Requests.Option[] + ).filter((option) => option.id === appliedRolesValue[i]); if (filteredOption.length !== 1) { return Promise.reject(errors.cookArgumentError()); } @@ -1131,12 +1296,15 @@ export function getAppliedRoles(form: Requests.Form): Promise { if ( !questionsExistOther || - questionCheckOther.data?.value == null + (questionCheckOther.data as Requests.Question).value == null ) { return Promise.reject(errors.cookArgumentError()); } - appliedRoles.push(questionCheckOther.data.value as string); + appliedRoles.push( + (questionCheckOther.data as Requests.Question) + .value as string + ); } else { appliedRoles.push(filteredOption[0].text); } @@ -1180,16 +1348,14 @@ export async function addPersonToDatabase( if (checkIfEmailInDb.length > 0) { await ormP.updatePerson({ personId: checkIfEmailInDb[0].person_id, - firstname: formResponse.birthName, - lastname: formResponse.lastName, + name: formResponse.name, github: null, email: formResponse.email, }); personId = checkIfEmailInDb[0].person_id; } else { const person = await ormP.createPerson({ - firstname: formResponse.birthName, - lastname: formResponse.lastName, + name: formResponse.name, email: formResponse.email, }); personId = person.person_id; @@ -1443,6 +1609,7 @@ export async function addRolesToDatabase( const created_role = await ormRo.createRole( formResponse.roles[role_index] ); + await ormAppRo.createAppliedRole({ jobApplicationId: job_application_id, roleId: created_role.role_id, @@ -1468,9 +1635,6 @@ export async function createForm( req: express.Request ): Promise { const parsedRequest = await rq.parseFormRequest(req); - if (parsedRequest.data.fields == undefined) { - return Promise.reject(errors.cookArgumentError()); - } const questionInBelgium: Responses.FormResponse = filterQuestion(parsedRequest, config.liveInBelgium); @@ -1483,16 +1647,19 @@ export async function createForm( ]); if ( !questionsExist || - questionInBelgium.data?.value == null || - questionCanWorkEnough.data?.value == null + (questionInBelgium.data as Requests.Question).value == null || + (questionCanWorkEnough.data as Requests.Question).value == null ) { return Promise.reject(errors.cookArgumentError()); } const wordInAnswerInBelgium: Responses.FormResponse = - checkWordInAnswer(questionInBelgium.data, "yes"); + checkWordInAnswer(questionInBelgium.data as Requests.Question, "yes"); const wordInAnswerCanWorkEnough: Responses.FormResponse = - checkWordInAnswer(questionCanWorkEnough.data, "yes"); + checkWordInAnswer( + questionCanWorkEnough.data as Requests.Question, + "yes" + ); if ( wordInAnswerInBelgium.data == null || @@ -1538,6 +1705,15 @@ export async function createForm( return Promise.resolve({}); } +export async function readFile( + directoryPart: string | null, + file: string +): Promise { + const readFile = (path: string) => fs.readFileSync(path, "utf8"); + const fileData = readFile(path.join(__dirname, `${directoryPart}/${file}`)); + return Promise.resolve(JSON.parse(fileData)); +} + /** * Gets the router for all `/form/` related endpoints. * @returns An Express.js {@link express.Router} routing all `/form/` diff --git a/backend/routes/github.ts b/backend/routes/github.ts index 5b285006..edd5039b 100644 --- a/backend/routes/github.ts +++ b/backend/routes/github.ts @@ -14,7 +14,8 @@ import * as session_key from "./session_key.json"; // holds states that are currently active. States are required to validate // github callbacks. -export let states: string[] = []; +// export let states: string[] = []; +export const states: { [key: string]: string } = {}; /** * Gets the home URL for the github callback. @@ -22,8 +23,6 @@ export let states: string[] = []; */ export function getHome(): string { const root = `${process.env.GITHUB_AUTH_CALLBACK_URL}`; - // check if dev or production - console.log("Home is: " + root); return root; } @@ -33,9 +32,10 @@ export function getHome(): string { * * @returns The new state. */ -export function genState(): string { +export function genState(redirect: string): string { const state = crypto.randomBytes(64).join(""); - states.push(state); + // states.push(state); + states[state] = redirect; return state; } @@ -46,13 +46,14 @@ export function genState(): string { * @param state The state to check. * @returns True if the state is valid, otherwise false. */ -export function checkState(state: string) { - if (!states.includes(state)) { +export function checkState(state: string): string | false { + if (!(state in states)) { return false; } - states = states.filter((x) => x != state); - return true; + const frontend = states[state]; + delete states[state]; + return frontend; } // Step 1: redirect to github for identity @@ -65,7 +66,14 @@ export function checkState(state: string) { * `/github/challenge` on our server. This function only generates a new state, * makes it valid and then redirects. */ -export function ghIdentity(resp: express.Response): Promise { +export function ghIdentity( + req: express.Request, + resp: express.Response +): Promise { + const frontend = + "callback" in req.body + ? (req.body.callback as string) + : (process.env.FRONTEND as string); let url = "https://github.com/login/oauth/authorize?"; url += "client_id=" + process.env.GITHUB_CLIENT_ID; // add client id url += "&allow_signup=true"; // allow users to sign up to github itself @@ -74,8 +82,7 @@ export function ghIdentity(resp: express.Response): Promise { encodeURIComponent( getHome() + config.global.preferred + "/github/challenge" ); - url += "&state=" + genState(); - console.log("--- REDIRECTING TO GITHUB AT " + url + " ---"); + url += "&state=" + genState(frontend); return util.redirect(resp, url); } @@ -96,9 +103,11 @@ export async function ghExchangeAccessToken( return Promise.reject(config.apiErrors.github.argumentMissing); } - if (!checkState(req.query.state as string)) { + const stateCheck = checkState(req.query.state as string); + if (stateCheck === false) { return Promise.reject(config.apiErrors.github.illegalState); } + const frontend = stateCheck as string; return axios .post( @@ -119,14 +128,17 @@ export async function ghExchangeAccessToken( ) .then((ares) => parseGHLogin(ares.data)) .then((login) => ghSignupOrLogin(login)) - .then((result) => - util.redirect( - res, - process.env.FRONTEND + "/login/" + result.sessionkey - ) - ) + .then((result) => { + const url: string = + frontend + + "/login/" + + result.sessionkey + + "?is_signup=" + + result.is_signup; + return util.redirect(res, url); + }) .catch((err) => { - console.log("GITHUB ERROR " + err); + console.log("GITHUB ERROR " + JSON.stringify(err)); util.redirect( res, process.env.FRONTEND + @@ -163,7 +175,7 @@ export function githubNameChange( person: { github: string | null; person_id: number; - firstname: string; + name: string; login_user: { password: string | null; login_user_id: number; @@ -174,7 +186,7 @@ export function githubNameChange( } ): boolean { if (person.github != login.login) return true; - if (person.firstname != login.name) return true; + if (person.name != login.name) return true; return false; } @@ -186,7 +198,8 @@ export function githubNameChange( */ export async function ghSignupOrLogin( login: Requests.GHLogin -): Promise { +): Promise { + let isSignup = false; return ormP .getPasswordPersonByGithub(login.id) .then(async (person) => { @@ -200,7 +213,7 @@ export async function ghSignupOrLogin( .updatePerson({ personId: person.person_id, github: login.login, - firstname: login.name, + name: login.name, }) .then(() => person.login_user); } else { @@ -209,11 +222,11 @@ export async function ghSignupOrLogin( }) .catch(async (error) => { if ("is_not_existent" in error && error.is_not_existent) { + isSignup = true; return ormP .createPerson({ github: login.login, - firstname: login.name, - lastname: "", + name: login.name, github_id: login.id, }) .then((person) => @@ -249,6 +262,7 @@ export async function ghSignupOrLogin( sessionkey: newkey.session_key, is_admin: loginuser.is_admin, is_coach: loginuser.is_coach, + is_signup: isSignup, }) ); }); @@ -257,7 +271,7 @@ export async function ghSignupOrLogin( export function getRouter(): express.Router { const router: express.Router = express.Router(); - router.get("/", async (_, rs) => await ghIdentity(rs)); + router.get("/", async (rq, rs) => await ghIdentity(rq, rs)); router.get( "/challenge", async (req, res) => diff --git a/backend/routes/login.ts b/backend/routes/login.ts index 61922e67..50663a8b 100644 --- a/backend/routes/login.ts +++ b/backend/routes/login.ts @@ -8,13 +8,9 @@ import { import { parseLoginRequest, parseLogoutRequest } from "../request"; import { Responses } from "../types"; import * as util from "../utility"; - +import * as bcrypt from "bcrypt"; import * as session_key from "./session_key.json"; -function orDefault(v: T | undefined, def: T): T { - return v == undefined || false ? def : v; -} - /** * Attempts to log a user into the system. * @param req The Express.js request to extract all required data from. @@ -22,38 +18,56 @@ function orDefault(v: T | undefined, def: T): T { * `Promise.resolve`, failures using `Promise.reject`. */ export async function login(req: express.Request): Promise { - console.log("Calling login endpoint " + JSON.stringify(req.body)); return parseLoginRequest(req).then((parsed) => getPasswordPersonByEmail(parsed.name).then(async (pass) => { + // check if all the fields are filled in (== not null or undefined) if ( pass == null || pass.login_user == null || - pass?.login_user?.password != parsed.pass + pass.login_user.password == null ) { return Promise.reject({ http: 409, reason: "Invalid e-mail or password.", }); + } else { + const data = { + id: pass.login_user.login_user_id, + password: pass.login_user.password, + status: pass.login_user.account_status, + admin: pass.login_user.is_admin, + coach: pass.login_user.is_coach, + }; + // check if the passwords match! + const valid = await bcrypt.compare(parsed.pass, data.password); + if (!valid) { + return Promise.reject({ + http: 409, + reason: "Invalid e-mail or password.", + }); + } + if (data.status == "DISABLED") { + return Promise.reject({ + http: 409, + reason: "Account is disabled.", + }); + } + const key: string = util.generateKey(); + const futureDate = new Date(Date.now()); + futureDate.setDate( + futureDate.getDate() + session_key.valid_period + ); + return addSessionKey( + pass.login_user.login_user_id, + key, + futureDate + ).then((ins) => ({ + sessionkey: ins.session_key, + is_admin: data.admin, + is_coach: data.coach, + account_status: data.status, + })); } - if (pass?.login_user?.account_status == "DISABLED") { - return Promise.reject({ - http: 409, - reason: "Account is disabled.", - }); - } - const key: string = util.generateKey(); - const futureDate = new Date(); - futureDate.setDate(futureDate.getDate() + session_key.valid_period); - return addSessionKey( - pass.login_user.login_user_id, - key, - futureDate - ).then((ins) => ({ - sessionkey: ins.session_key, - is_admin: orDefault(pass?.login_user?.is_admin, false), - is_coach: orDefault(pass?.login_user?.is_coach, false), - account_status: pass?.login_user?.account_status, - })); }) ); } diff --git a/backend/routes/osoc.ts b/backend/routes/osoc.ts index ccc3c5c8..c02c5d88 100644 --- a/backend/routes/osoc.ts +++ b/backend/routes/osoc.ts @@ -2,8 +2,9 @@ import express from "express"; import * as rq from "../request"; import { Responses } from "../types"; import * as util from "../utility"; -import { errors } from "../utility"; +import { checkYearPermissionOsoc, errors } from "../utility"; import * as ormO from "../orm_functions/osoc"; +import { addOsocToUser } from "../orm_functions/login_user_osoc"; /** * Attempts to create a new project in the system. @@ -18,14 +19,19 @@ export async function createOsocEdition( .parseNewOsocEditionRequest(req) .then((parsed) => util.isAdmin(parsed)) .then(async (parsed) => { - return ormO.createOsoc(parsed.data.year).then((osoc) => - Promise.resolve({ - data: { - id: osoc.osoc_id, - year: osoc.year, - }, - }) - ); + const osoc = await ormO.createOsoc(parsed.data.year); + // the loginUser (an admin) created this osoc edition. The user is immediately registered as someone who should see this osoc edition + const added = await addOsocToUser(parsed.userId, osoc.osoc_id); + if (!added) { + // this error only happens if shomething in the database goes wrong even though we just checked all the necessary data is there + return Promise.reject(errors.cookServerError()); + } + return Promise.resolve({ + data: { + id: osoc.osoc_id, + year: osoc.year, + }, + }); }); } @@ -39,17 +45,14 @@ export async function listOsocEditions( req: express.Request ): Promise { const parsedRequest = await rq.parseOsocAllRequest(req); - const checkedSessionKey = await util - .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); + const checkedSessionKey = await util.isAdmin(parsedRequest); + if (checkedSessionKey.is_admin) { + const osocEditions = await ormO.getAllOsoc(); + + return Promise.resolve({ data: osocEditions }); } - const osocEditions = await ormO.getAllOsoc(); - return Promise.resolve({ - data: osocEditions, - }); + return Promise.reject(errors.cookInvalidID()); } /** @@ -62,21 +65,19 @@ export async function filterYear( req: express.Request ): Promise { const parsedRequest = await rq.parseFilterOsocsRequest(req); - const checkedSessionKey = await util - .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } + const checkedSessionKey = await util.checkSessionKey(parsedRequest); const osocs = await ormO.filterOsocs( + { + currentPage: parsedRequest.currentPage, + pageSize: parsedRequest.pageSize, + }, checkedSessionKey.data.yearFilter, - checkedSessionKey.data.yearSort + checkedSessionKey.data.yearSort, + checkedSessionKey.userId ); - return Promise.resolve({ - data: osocs, - }); + return Promise.resolve(osocs); } /** @@ -90,6 +91,7 @@ export async function deleteOsocEditionRequest( return rq .parseDeleteOsocEditionRequest(req) .then((parsed) => util.isAdmin(parsed)) + .then(checkYearPermissionOsoc) .then(async (parsed) => { return ormO .deleteOsocFromDB(parsed.data.id) diff --git a/backend/routes/project.ts b/backend/routes/project.ts index ac36b20d..06f17961 100644 --- a/backend/routes/project.ts +++ b/backend/routes/project.ts @@ -6,11 +6,16 @@ import * as ormOsoc from "../orm_functions/osoc"; import * as ormPr from "../orm_functions/project"; import * as ormPrRole from "../orm_functions/project_role"; import * as ormPU from "../orm_functions/project_user"; +import * as ormC from "../orm_functions/contract"; +import * as ormOs from "../orm_functions/osoc"; import * as ormRole from "../orm_functions/role"; import * as rq from "../request"; -import { InternalTypes, Responses, StringDict } from "../types"; +import { ApiError, Responses } from "../types"; import * as util from "../utility"; -import { errors } from "../utility"; +import { checkYearPermissionProject, errors } from "../utility"; +import { getOsocById } from "../orm_functions/osoc"; +import { getOsocYearsForLoginUser } from "../orm_functions/login_user"; +import { getJobApplication } from "../orm_functions/job_application"; /** * Attempts to create a new project in the system. @@ -21,31 +26,72 @@ import { errors } from "../utility"; export async function createProject( req: express.Request ): Promise { - return rq - .parseNewProjectRequest(req) - .then((parsed) => util.isAdmin(parsed)) - .then(async (parsed) => { - return ormPr - .createProject({ - name: parsed.data.name, - partner: parsed.data.partner, - startDate: new Date(parsed.data.start), - endDate: new Date(parsed.data.end), - positions: Number(parsed.data.positions), - osocId: Number(parsed.data.osocId), - }) - .then((project) => - Promise.resolve({ - id: project.project_id, - name: project.name, - partner: project.partner, - start_date: project.start_date.toString(), - end_date: project.end_date.toString(), - positions: project.positions, - osoc_id: project.osoc_id, - }) - ); + const parsedRequest = await rq.parseNewProjectRequest(req); + const checkedSessionKey = await util.isAdmin(parsedRequest); + + // check if the loginUser has the permissions to create a project for this osoc edition + const visibleYears = await getOsocYearsForLoginUser( + checkedSessionKey.userId + ); + const osoc = await getOsocById(checkedSessionKey.data.osocId); + if (osoc && !visibleYears.includes(osoc.year)) { + return Promise.reject(errors.cookInsufficientRights()); + } + + const latestOsoc = await ormOsoc.getLatestOsoc(); + + if (latestOsoc === null || osoc === null || osoc.year !== latestOsoc.year) { + return Promise.reject(errors.cookWrongOsocYear()); + } + + const createdProject = await ormPr.createProject({ + name: checkedSessionKey.data.name, + partner: checkedSessionKey.data.partner, + startDate: new Date(checkedSessionKey.data.start), + endDate: new Date(checkedSessionKey.data.end), + osocId: Number(checkedSessionKey.data.osocId), + description: checkedSessionKey.data.description, + }); + + const roleList: { name: string; positions: number }[] = []; + + for (const role of checkedSessionKey.data.roles.roles) { + let roleByName = await ormRole.getRolesByName(role.name); + if (roleByName === null) { + roleByName = await ormRole.createRole(role.name); + } + const createdProjectRole = await ormPrRole.createProjectRole({ + projectId: createdProject.project_id, + roleId: roleByName.role_id, + positions: role.positions, }); + + roleList.push({ + name: role.name, + positions: createdProjectRole.positions, + }); + } + + for (const coachId of checkedSessionKey.data.coaches.coaches) { + await ormPU.createProjectUser({ + projectId: createdProject.project_id, + loginUserId: coachId, + }); + } + + const coaches = await ormPU.getUsersFor(createdProject.project_id); + + return Promise.resolve({ + id: createdProject.project_id, + name: createdProject.name, + partner: createdProject.partner, + start_date: createdProject.start_date.toString(), + end_date: createdProject.end_date.toString(), + osoc_id: createdProject.osoc_id, + description: createdProject.description, + roles: roleList, + coaches: coaches, + }); } /** @@ -56,42 +102,94 @@ export async function createProject( */ export async function listProjects( req: express.Request -): Promise { - return rq +): Promise { + const checkedSessionKey = await rq .parseProjectAllRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) - .then(async () => - ormPr - .getAllProjects() - .then((obj) => - Promise.all( - obj.map(async (val) => { - const students = await ormCtr.contractsByProject( - val.project_id - ); - const users = await ormPU.getUsersFor( - val.project_id - ); - return Promise.resolve({ - id: Number(val.project_id), - name: val.name, - partner: val.partner, - start_date: val.start_date.toString(), - end_date: val.end_date.toString(), - positions: val.positions, - osoc_id: val.osoc_id, - students: students, - coaches: users, - }); - }) - ) - ) - .then((obj) => - Promise.resolve({ - data: obj, - }) - ) + .then(util.checkSessionKey); + + const allProjects = []; + const fetchedProjects = await ormPr.filterProjects( + { + currentPage: checkedSessionKey.data.currentPage, + pageSize: checkedSessionKey.data.pageSize, + }, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + checkedSessionKey.userId + ); + for (const project of fetchedProjects.data) { + const roles = await ormPrRole.getProjectRolesByProject( + project.project_id ); + const projectRoles = []; + for (const role of roles) { + const foundRole = await ormRole.getRole(role.role_id); + if (foundRole === null) { + return Promise.reject(errors.cookNoDataError()); + } + projectRoles.push({ + name: foundRole.name, + positions: role.positions, + }); + } + + const contracts = await ormCtr.contractsByProject(project.project_id); + + const newContracts: Responses.Contract[] = []; + + contracts.forEach((contract) => { + const newStudentField = { + evaluations: undefined, + evaluation: undefined, + jobApplication: undefined, + roles: undefined, + student: + contract.student === null + ? contract.student + : { + student_id: contract.student.student_id, + person_id: undefined, + person: contract.student.person, + alumni: contract.student.alumni, + nickname: contract.student.nickname, + gender: contract.student.gender, + pronouns: contract.student.pronouns, + phone_number: contract.student.phone_number, + }, + }; + + newContracts.push({ + project_role: contract.project_role, + contract_id: contract.contract_id, + contract_status: contract.contract_status, + login_user: contract.login_user, + student: newStudentField, + }); + }); + + const users = await ormPU.getUsersFor(project.project_id); + allProjects.push({ + id: Number(project.project_id), + name: project.name, + partner: project.partner, + start_date: project.start_date.toString(), + end_date: project.end_date.toString(), + osoc_id: project.osoc_id, + description: project.description, + roles: projectRoles, + contracts: newContracts, + coaches: users, + }); + } + + return Promise.resolve({ + pagination: fetchedProjects.pagination, + data: allProjects, + }); } /** @@ -102,67 +200,205 @@ export async function listProjects( */ export async function getProject( req: express.Request -): Promise { - return rq - .parseSingleProjectRequest(req) - .then((parsed) => util.isAdmin(parsed)) - .then((parsed) => util.isValidID(parsed.data, "project")) - .then(async (parsed) => - ormPr.getProjectById(parsed.id).then(async (obj) => { - if (obj !== null) { - const students = await ormCtr.contractsByProject( - obj.project_id - ); - const users = await ormPU.getUsersFor(obj.project_id); - return Promise.resolve({ - id: Number(obj.project_id), - name: obj.name, - partner: obj.partner, - start_date: obj.start_date.toString(), - end_date: obj.end_date.toString(), - positions: obj.positions, - osoc_id: obj.osoc_id, - students: students, - coaches: users, - }); - } else { - return Promise.reject(errors.cookInvalidID()); - } - }) +): Promise { + const parsedRequest = await rq.parseSingleProjectRequest(req); + const checkedId = await util + .isAdmin(parsedRequest) + .then(checkYearPermissionProject) + .then((v) => util.isValidID(v.data, "project")); + + const project = await ormPr.getProjectById(checkedId.id); + if (project !== null) { + const contracts = await ormCtr.contractsByProject(project.project_id); + + const newContracts: Responses.Contract[] = []; + + contracts.forEach((contract) => { + const newStudentField = { + evaluations: undefined, + evaluation: undefined, + jobApplication: undefined, + roles: undefined, + student: + contract.student === null + ? null + : { + student_id: contract.student.student_id, + person_id: undefined, + person: contract.student.person, + alumni: contract.student.alumni, + nickname: contract.student.nickname, + gender: contract.student.gender, + pronouns: contract.student.pronouns, + phone_number: contract.student.phone_number, + }, + }; + + newContracts.push({ + project_role: contract.project_role, + contract_id: contract.contract_id, + contract_status: contract.contract_status, + login_user: contract.login_user, + student: newStudentField, + }); + }); + + const roles = await ormPrRole.getProjectRolesByProject( + project.project_id ); + const projectRoles = []; + for (const role of roles) { + const foundRole = await ormRole.getRole(role.role_id); + if (foundRole === null) { + return Promise.reject(errors.cookNoDataError()); + } + projectRoles.push({ + name: foundRole.name, + positions: role.positions, + }); + } + + const users = await ormPU.getUsersFor(project.project_id); + + return Promise.resolve({ + id: Number(project.project_id), + name: project.name, + partner: project.partner, + start_date: project.start_date.toString(), + end_date: project.end_date.toString(), + osoc_id: project.osoc_id, + description: project.description, + roles: projectRoles, + contracts: newContracts, + coaches: users, + }); + } + + return Promise.reject(errors.cookInvalidID()); } export async function modProject( req: express.Request ): Promise { - return rq + const checkedId = await rq .parseUpdateProjectRequest(req) - .then((parsed) => util.isAdmin(parsed)) - .then((parsed) => util.isValidID(parsed.data, "project")) - .then(async (parsed) => { - // UPDATING LOGIC - return ormPr - .updateProject({ - projectId: parsed.id, - name: parsed.name, - partner: parsed.partner, - startDate: parsed.start, - endDate: parsed.end, - positions: parsed.positions, - osocId: parsed.osocId, - }) - .then((project) => - Promise.resolve({ - id: project.project_id, - name: project.name, - partner: project.partner, - start_date: project.start_date.toString(), - end_date: project.end_date.toString(), - positions: project.positions, - osoc_id: project.osoc_id, - }) - ); + .then(util.isAdmin) + .then(checkYearPermissionProject) + .then((checked) => util.isValidID(checked.data, "project")); + + const project = await ormPr.getProjectById(checkedId.id); + + const osoc = await ormOsoc.getLatestOsoc(); + + if (project === null) { + return Promise.reject(errors.cookInvalidID()); + } + + if (osoc === null || project.osoc.year !== osoc.year) { + return Promise.reject(errors.cookWrongOsocYear()); + } + + const updatedProject = await ormPr.updateProject({ + projectId: checkedId.id, + name: checkedId.name, + partner: checkedId.partner, + startDate: checkedId.start, + endDate: checkedId.end, + osocId: checkedId.osocId, + description: checkedId.description, + }); + + // current state (before change) + const oldProjectRoles = await ormPrRole.getProjectRoleNamesByProject( + checkedId.id + ); + + let isOldRole = false; + if (checkedId.roles !== undefined) { + // iterate over roles which have been sent + for (const role of checkedId.roles.roles) { + isOldRole = false; + for (const projectRole of oldProjectRoles) { + if (role.name === projectRole.role.name) { + isOldRole = true; + // check if valid -> positions = 0 => delete + if (role.positions !== projectRole.positions) { + if (role.positions === 0) { + await ormPrRole.deleteProjectRole( + projectRole.project_role_id + ); + } else { + // update #positions + await ormPrRole.updateProjectRole({ + projectRoleId: projectRole.project_role_id, + projectId: checkedId.id, + roleId: projectRole.role_id, + positions: role.positions, + }); + } + } + break; + } + } + // if new role: create + if (!isOldRole && role.positions > 0) { + const project_role = await ormRole.getRolesByName(role.name); + if (project_role !== null) { + await ormPrRole.createProjectRole({ + projectId: checkedId.id, + roleId: project_role.role_id, + positions: role.positions, + }); + } + } + } + } + + const projectRoles = await ormPrRole.getProjectRolesByProject(checkedId.id); + const roles: { name: string; positions: number }[] = []; + for (const projectRole of projectRoles) { + const foundRole = await ormRole.getRole(projectRole.role_id); + if (foundRole === null) { + return Promise.reject(errors.cookNoDataError()); + } + + roles.push({ + name: foundRole.name, + positions: projectRole.positions, }); + } + + if (checkedId.addCoaches !== undefined) { + for (const coachId of checkedId.addCoaches.coaches) { + await ormPU.createProjectUser({ + projectId: checkedId.id, + loginUserId: coachId, + }); + } + } + + if (checkedId.removeCoaches !== undefined) { + for (const coachId of checkedId.removeCoaches.coaches) { + await ormPU.deleteProjectUser({ + projectId: checkedId.id, + loginUserId: coachId, + }); + } + } + + const coachList = await ormPU.getUsersFor(Number(checkedId.id)); + + return Promise.resolve({ + id: updatedProject.project_id, + name: updatedProject.name, + partner: updatedProject.partner, + start_date: updatedProject.start_date.toString(), + end_date: updatedProject.end_date.toString(), + osoc_id: updatedProject.osoc_id, + roles: roles, + description: updatedProject.description, + coaches: coachList, + }); } /** @@ -177,52 +413,39 @@ export async function deleteProject( return rq .parseDeleteProjectRequest(req) .then((parsed) => util.isAdmin(parsed)) + .then(checkYearPermissionProject) .then((parsed) => util.isValidID(parsed.data, "project")) .then(async (parsed) => { + const [project, latestOsoc] = await Promise.all([ + ormPr.getProjectById(parsed.id), + ormOsoc.getLatestOsoc(), + ]); + + if (project === null || latestOsoc === null) { + return Promise.reject(errors.cookInvalidID()); + } + + if (project.osoc.year === latestOsoc.year) { + for (const contract of await ormC.contractsByProject( + parsed.id + )) { + await ormCtr.removeContract(contract.contract_id); + } + } return ormPr - .deleteProject(parsed.id) + .deleteProjectFromDB(parsed.id) .then(() => Promise.resolve({})); }); } -/** - * Attempts to get all drafted students in the system for a project. - * @param req The Express.js request to extract all required data from. - * @returns See the API documentation. Successes are passed using - * `Promise.resolve`, failures using `Promise.reject`. - */ -export async function getDraftedStudents( - req: express.Request -): Promise { - return rq - .parseGetDraftedStudentsRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) - .then(async (parsed) => { - const prName = await ormPr - .getProjectById(parsed.data.id) - .then((pr) => pr?.name); - - return ormCtr.contractsByProject(parsed.data.id).then(async (arr) => - Promise.resolve({ - id: parsed.data.id, - name: util.getOrDefault(prName, "(unnamed project)"), - students: arr.map((obj) => ({ - student: obj.student, - status: obj.contract_status, - })), - }) - ); - }); -} - export async function getFreeSpotsFor( role: string, project: number -): Promise<{ count: number; role: number }> { +): Promise<{ count: number; role_id: number; project_role_id: number }> { return ormPrRole .getProjectRolesByProject(project) - .then((roles) => - Promise.all( + .then((roles) => { + return Promise.all( roles.map(async (r) => ormRole.getRole(r.role_id).then((upd) => Promise.resolve({ @@ -232,11 +455,12 @@ export async function getFreeSpotsFor( }) ) ) - ) - ) - .then((roles) => roles.filter((r) => r.block?.name == role)) + ); + }) + .then((roles) => { + return roles.filter((r) => r.block?.name == role); + }) .then(async (rest) => { - console.log("Resulting roles: " + JSON.stringify(rest)); if (rest.length != 1) return Promise.reject(); return ormPrRole .getNumberOfFreePositions(rest[0].project_role_id) @@ -244,7 +468,8 @@ export async function getFreeSpotsFor( if (n == null) return Promise.reject(); return Promise.resolve({ count: n, - role: rest[0].project_role_id, + role_id: rest[0].role_id, + project_role_id: rest[0].project_role_id, }); }); }); @@ -253,7 +478,7 @@ export async function getFreeSpotsFor( export async function createProjectRoleFor( project: number, role: string -): Promise<{ count: number; role: number }> { +): Promise<{ count: number; project_role_id: number }> { return ormRole .getRolesByName(role) .then((r) => { @@ -269,82 +494,109 @@ export async function createProjectRoleFor( }); }) .then((res) => - Promise.resolve({ count: res.positions, role: res.project_role_id }) + Promise.resolve({ + count: res.positions, + project_role_id: res.project_role_id, + }) ); } -export async function modProjectStudent( +export async function unAssignCoach( req: express.Request -): Promise { +): Promise { return rq - .parseDraftStudentRequest(req) - .then((parsed) => util.isAdmin(parsed)) - .then(async (parsed) => { - console.log( - "Attempting to modify project " + - parsed.data.id + - " by moving student " + - parsed.data.studentId + - " to role `" + - parsed.data.role + - "`" - ); - return ormCtr - .contractsByProject(parsed.data.id) - .then((arr) => - arr.filter( - (v) => v.student.student_id == parsed.data.studentId + .parseRemoveCoachRequest(req) + .then((parsed) => util.checkSessionKey(parsed)) + .then(async (checked) => { + const project = await ormPr.getProjectById(checked.data.id); + + const osoc = await ormOsoc.getLatestOsoc(); + + if (project === null) { + return Promise.reject(errors.cookInvalidID()); + } + + if (osoc === null || project.osoc.year !== osoc.year) { + return Promise.reject(errors.cookWrongOsocYear()); + } + + return ormPU + .getUsersFor(Number(checked.data.id)) + .then((project_users) => + project_users.filter( + (project_user) => + project_user.login_user.login_user_id == + checked.data.loginUserId ) ) - .then((arr) => { - if (arr.length == 0) { + .then(async (found) => { + if (found.length == 0) { return Promise.reject({ - http: 204, - reason: "The selected student is not assigned to this project.", + http: 400, + reason: + "The coach with ID " + + checked.data.loginUserId.toString() + + " is not assigned to project " + + checked.data.id, }); } + await ormPU.deleteProjectUser({ + projectId: checked.data.id, + loginUserId: checked.data.loginUserId, + }); - if (arr.length > 1) { + return Promise.resolve({}); + }); + }); +} + +export async function assignCoach( + req: express.Request +): Promise { + return rq + .parseAssignCoachRequest(req) + .then((parsed) => util.checkSessionKey(parsed)) + .then(async (checked) => { + const project = await ormPr.getProjectById(checked.data.id); + + const osoc = await ormOsoc.getLatestOsoc(); + + if (project === null) { + return Promise.reject(errors.cookInvalidID()); + } + + if (osoc === null || project.osoc.year !== osoc.year) { + return Promise.reject(errors.cookWrongOsocYear()); + } + + return ormPU + .getUsersFor(Number(checked.data.id)) + .then((project_users) => + project_users.filter( + (project_user) => + project_user.login_user.login_user_id == + checked.data.loginUserId + ) + ) + .then(async (found) => { + if (found.length != 0) { return Promise.reject({ - http: 409, - reason: "The request is ambiguous.", + http: 400, + reason: + "The coach with ID " + + checked.data.loginUserId.toString() + + " is already assigned to project " + + checked.data.id, }); } - return Promise.resolve(arr[0]); - }) - .then(async (ctr) => { - return getFreeSpotsFor(parsed.data.role, parsed.data.id) - .catch(() => - createProjectRoleFor( - parsed.data.id, - parsed.data.role - ) - ) - .then((remaining) => { - if (remaining.count <= 0) { - return Promise.reject({ - http: 409, - reason: "Can't add this role to the student. There are no more vacant spots.", - }); - } - - return ormCtr.updateContract({ - contractId: ctr.contract_id, - loginUserId: parsed.userId, - projectRoleId: remaining.role, - }); - }); - }) - .then((res) => - ormPrRole.getProjectRoleById(res.project_role_id) - ) - .then((res) => - Promise.resolve({ - drafted: true, - role: util.getOrDefault(res?.role.name, ""), - }) - ); + const project_user = await ormPU.createProjectUser({ + projectId: checked.data.id, + loginUserId: checked.data.loginUserId, + }); + + return Promise.resolve(project_user); + }); }); } @@ -354,9 +606,32 @@ export async function unAssignStudent( return rq .parseRemoveAssigneeRequest(req) .then((parsed) => util.checkSessionKey(parsed)) + .then(checkYearPermissionProject) .then(async (checked) => { + const project = await ormPr.getProjectById(checked.data.id); + + const osoc = await ormOsoc.getLatestOsoc(); + + if (project === null) { + return Promise.reject(errors.cookInvalidID()); + } + + if (osoc === null || project.osoc.year !== osoc.year) { + return Promise.reject(errors.cookWrongOsocYear()); + } + return ormCtr .contractsForStudent(Number(checked.data.studentId)) + .then((ctrs) => + Promise.all( + ctrs.map((x) => + util.getOrReject(x.project_role).then((y) => ({ + ...x, + project_role: y, + })) + ) + ) + ) .then((ctrs) => ctrs.filter( (contr) => @@ -379,89 +654,117 @@ export async function unAssignStudent( await ormEv .getEvaluationByPartiesFor( checked.userId, - contr.student.student_id, + contr.student?.student_id, contr.project_role.project.osoc_id ) - .then((evl) => { - if (evl.length != 1) { - return Promise.reject({ - http: 400, - reason: "Multiple evaluations match.", + .then(async (evl) => { + for (let i = 0; i < evl.length; i++) { + await ormEv.updateEvaluationForStudent({ + evaluation_id: evl[i].evaluation_id, + loginUserId: checked.userId, + motivation: + util.getOrDefault( + evl[i].motivation, + "" + ) + + " [Removed assignee from project " + + checked.data.id + + "]", }); } - - return ormEv.updateEvaluationForStudent({ - evaluation_id: evl[0].evaluation_id, - loginUserId: checked.userId, - motivation: - util.getOrDefault( - evl[0].motivation, - "" - ) + - " [Removed assignee from project " + - checked.data.id + - "]", - }); }) .then(() => ormCtr.removeContract(contr.contract_id) ); } - return Promise.resolve({}); }); }); } -export async function getProjectConflicts( +export async function assignStudent( req: express.Request -): Promise { - return rq - .parseProjectConflictsRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) - .then(async () => { - return ormOsoc - .getNewestOsoc() - .then((osoc) => util.getOrReject(osoc)) - .then((osoc) => - ormCtr.sortedContractsByOsocEdition(osoc.osoc_id) - ) - .then((contracts) => { - if (contracts.length == 0 || contracts.length == 1) - return Promise.resolve([]); - const res: StringDict = {}; - let latestid = contracts[0].student_id; - for (let i = 1; i < contracts.length; i++) { - if (contracts[i].student_id == latestid) { - const idStr: string = - contracts[i].student_id.toString(); - if (!(idStr in res)) { - res[idStr] = [contracts[i - 1], contracts[i]]; - } else { - res[idStr].push(contracts[i]); - } - } - latestid = contracts[i].student_id; - } +): Promise { + const alreadyContract: ApiError = { + http: 409, + reason: "This student does already have a contract", + }; + const nonexist: ApiError = { + http: 404, + reason: "That role doesn't exist", + }; + const noplace: ApiError = { + http: 409, + reason: "There are no more free spaces for that role", + }; + + // authenticate, parse, ... + const checked = await rq + .parseDraftStudentRequest(req) + .then((parsed) => util.isAdmin(parsed)); - const arr: InternalTypes.Conflict[] = []; - for (const idStr in res) { - arr.push({ - student: Number(idStr), - projects: res[idStr].map((p) => ({ - id: p.project_role.project.project_id, - name: p.project_role.project.name, - })), - }); - } - return Promise.resolve(arr); - }) - .then((arr) => - Promise.resolve({ - data: arr, - }) - ); + // check if edition is ready + const latestOsoc = await ormOsoc + .getLatestOsoc() + .then((osoc) => util.getOrReject(osoc)); + + const jobApplication = await getJobApplication( + checked.data.jobApplicationId + ); + const project = await ormPr.getProjectById(checked.data.id); + + if (project === null || jobApplication === null) { + return Promise.reject(errors.cookInvalidID()); + } + + if (project.osoc.year !== jobApplication.osoc.year) { + return Promise.reject({ + http: 403, + reason: "Student application and project are from different osoc editions", }); + } + + if (project.osoc.year !== latestOsoc.year) { + return Promise.reject(errors.cookWrongOsocYear()); + } + + // check if no contracts yet + await ormCtr + .contractsForStudent(checked.data.studentId) + .then((data) => + Promise.all(data.map((x) => util.getOrReject(x.project_role))) + ) + .then((data) => { + return data.filter((x) => x.project.osoc_id === latestOsoc.osoc_id); + }) + .then((filtered) => { + return filtered.length > 0 + ? Promise.reject(alreadyContract) + : Promise.resolve(); + }); + + // get project role + // then create contract + // then assign + return getFreeSpotsFor(checked.data.role, checked.data.id) + .catch(() => Promise.reject(nonexist)) + .then((r) => + r.count > 0 ? Promise.resolve(r) : Promise.reject(noplace) + ) + .then((r) => + ormCtr + .createContract({ + studentId: checked.data.studentId, + projectRoleId: r.project_role_id, + loginUserId: checked.userId, + contractStatus: "DRAFT", + }) + .then(() => { + return ormRole.getRole(r.role_id); + }) + ) + .then(util.getOrReject) + .then((r) => Promise.resolve({ drafted: true, role: r.name })); } /** @@ -472,46 +775,105 @@ export async function getProjectConflicts( */ export async function filterProjects( req: express.Request -): Promise { +): Promise { const parsedRequest = await rq.parseFilterProjectsRequest(req); - const checkedSessionKey = await util - .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); + const checkedSessionKey = await util.checkSessionKey(parsedRequest); + + let year; + if (checkedSessionKey.data.osocYear === undefined) { + const latestOsocYear = await ormOs.getLatestOsoc(); + if (latestOsocYear !== null) { + year = latestOsocYear.year; + } else { + year = new Date().getFullYear(); + } + } else { + year = checkedSessionKey.data.osocYear; } const projects = await ormPr.filterProjects( + { + currentPage: checkedSessionKey.data.currentPage, + pageSize: checkedSessionKey.data.pageSize, + }, checkedSessionKey.data.projectNameFilter, checkedSessionKey.data.clientNameFilter, - checkedSessionKey.data.assignedCoachesFilterArray, checkedSessionKey.data.fullyAssignedFilter, + year, checkedSessionKey.data.projectNameSort, checkedSessionKey.data.clientNameSort, - checkedSessionKey.data.fullyAssignedSort + checkedSessionKey.userId ); - const projectlist = []; + const allProjects = []; + for (const project of projects.data) { + const roles = await ormPrRole.getProjectRolesByProject( + project.project_id + ); + const projectRoles = []; + for (const role of roles) { + const foundRole = await ormRole.getRole(role.role_id); + if (foundRole === null) { + return Promise.reject(errors.cookNoDataError()); + } + projectRoles.push({ + name: foundRole.name, + positions: role.positions, + }); + } - for (const project of projects) { const contracts = await ormCtr.contractsByProject(project.project_id); - const users = await ormPU.getUsersFor(project.project_id); - projectlist.push({ - id: project.project_id, + const newContracts: Responses.Contract[] = []; + + contracts.forEach((contract) => { + const newStudentField = { + evaluations: undefined, + evaluation: undefined, + jobApplication: undefined, + roles: undefined, + student: + contract.student === null + ? contract.student + : { + student_id: contract.student.student_id, + person_id: undefined, + person: contract.student.person, + alumni: contract.student.alumni, + nickname: contract.student.nickname, + gender: contract.student.gender, + pronouns: contract.student.pronouns, + phone_number: contract.student.phone_number, + }, + }; + + newContracts.push({ + project_role: contract.project_role, + contract_id: contract.contract_id, + contract_status: contract.contract_status, + login_user: contract.login_user, + student: newStudentField, + }); + }); + + const users = await ormPU.getUsersFor(project.project_id); + allProjects.push({ + id: Number(project.project_id), name: project.name, partner: project.partner, - start_date: project.start_date, - end_data: project.end_date, - positions: project.positions, + start_date: project.start_date.toString(), + end_date: project.end_date.toString(), osoc_id: project.osoc_id, - contracts: contracts, + description: project.description, + roles: projectRoles, + contracts: newContracts, coaches: users, }); } return Promise.resolve({ - data: projectlist, + pagination: projects.pagination, + data: allProjects, }); } @@ -533,12 +895,10 @@ export function getRouter(): express.Router { util.route(router, "post", "/:id", modProject); util.route(router, "delete", "/:id", deleteProject); - util.route(router, "get", "/:id/draft", getDraftedStudents); - util.route(router, "post", "/:id/draft", modProjectStudent); - + util.route(router, "post", "/:id/assignee", assignStudent); util.route(router, "delete", "/:id/assignee", unAssignStudent); - - util.route(router, "get", "/conflicts", getProjectConflicts); + util.route(router, "delete", "/:id/coach", unAssignCoach); + util.route(router, "post", "/:id/coach", assignCoach); // TODO add project conflicts util.addAllInvalidVerbs(router, [ diff --git a/backend/routes/reset.ts b/backend/routes/reset.ts index 23987e65..b7da16f4 100644 --- a/backend/routes/reset.ts +++ b/backend/routes/reset.ts @@ -11,6 +11,7 @@ import * as rq from "../request"; import { Email, Responses } from "../types"; import * as util from "../utility"; import * as session_key from "./session_key.json"; +import * as bcrypt from "bcrypt"; export async function sendMail(mail: Email) { const oauthclient = new gapi.Auth.OAuth2Client( @@ -31,7 +32,10 @@ export async function sendMail(mail: Email) { ); } }) - .catch((e) => console.log("Email error:" + JSON.stringify(e))); + .catch((e) => { + console.log("Email error:" + JSON.stringify(e)); + return Promise.reject(config.apiErrors.reset.sendEmail); + }); const transp = nodemailer.createTransport({ service: "gmail", @@ -84,18 +88,12 @@ export async function requestReset( util.generateKey(), date ) - .catch((e) => { - console.log(e); - return Promise.reject(); - }) .then(async (code) => { return sendMail({ to: parsed.email, subject: config.email.header, html: createEmail(code.reset_id), - }).then((data) => { - console.log(data); - nodemailer.getTestMessageUrl(data); + }).then(() => { return Promise.resolve({}); }); }); @@ -141,6 +139,12 @@ export async function resetPassword( if (code == null || code.valid_until < new Date(Date.now())) return Promise.reject(util.errors.cookArgumentError()); + // calculate the hash of the new password + const hash = await bcrypt.hash( + parsed.password, + config.encryption.encryptionRounds + ); + return ormLU .getLoginUserById(code.login_user_id) .then((user) => { @@ -150,11 +154,10 @@ export async function resetPassword( isAdmin: user.is_admin, isCoach: user.is_coach, accountStatus: user?.account_status, - password: parsed.password, + password: hash, }); }) .then((user) => { - console.log(JSON.stringify(user)); const futureDate = new Date(); futureDate.setDate( futureDate.getDate() + session_key.valid_period diff --git a/backend/routes/role.ts b/backend/routes/role.ts index 2a18ad40..a323d096 100644 --- a/backend/routes/role.ts +++ b/backend/routes/role.ts @@ -3,6 +3,7 @@ import { Responses } from "../types"; import * as rq from "../request"; import * as util from "../utility"; import * as ormRo from "../orm_functions/role"; +import * as ormRole from "../orm_functions/role"; /** * Attempts to list all roles in the system. @@ -12,11 +13,11 @@ import * as ormRo from "../orm_functions/role"; */ export async function listStudentRoles( req: express.Request -): Promise { +): Promise { return rq .parseRolesAllRequest(req) .then((parsed) => util.checkSessionKey(parsed)) - .then(() => { + .then(async () => { return ormRo.getAllRoles().then((roles) => Promise.resolve({ data: roles, @@ -38,8 +39,14 @@ export async function createStudentRole( .parseStudentRoleRequest(req) .then((parsed) => util.checkSessionKey(parsed)) .then(async (parsed) => { - return ormRo.createRole(parsed.data.name).then((role) => { - return Promise.resolve({ name: role.name, id: role.role_id }); + let roleByName = await ormRole.getRolesByName(parsed.data.name); + if (roleByName === null) { + roleByName = await ormRole.createRole(parsed.data.name); + } + + return Promise.resolve({ + name: roleByName.name, + id: roleByName.role_id, }); }); } diff --git a/backend/routes/student.ts b/backend/routes/student.ts index e38ed238..6ca75c10 100644 --- a/backend/routes/student.ts +++ b/backend/routes/student.ts @@ -8,87 +8,10 @@ import * as ormSt from "../orm_functions/student"; import * as ormLU from "../orm_functions/login_user"; import * as ormOs from "../orm_functions/osoc"; import * as rq from "../request"; -import { Responses } from "../types"; +import { Responses, InternalTypes } from "../types"; import * as util from "../utility"; -import { errors } from "../utility"; -import * as ormP from "../orm_functions/person"; - -/** - * Attempts to list all students in the system. - * @param req The Express.js request to extract all required data from. - * @returns See the API documentation. Successes are passed using - * `Promise.resolve`, failures using `Promise.reject`. - */ -export async function listStudents( - req: express.Request -): Promise { - const parsedRequest = await rq.parseStudentAllRequest(req); - const checkedSessionKey = await util - .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } - const studentList: object[] = []; - const students = await ormSt.getAllStudents(); - for (let studentIndex = 0; studentIndex < students.length; studentIndex++) { - const jobApplication = await ormJo.getLatestJobApplicationOfStudent( - students[studentIndex].student_id - ); - if (jobApplication != null) { - const roles = []; - for (const applied_role of jobApplication.applied_role) { - const role = await ormRo.getRole(applied_role.role_id); - if (role != null) { - roles.push(role.name); - } else { - return Promise.reject(errors.cookInvalidID()); - } - } - - const evaluations = await ormJo.getStudentEvaluationsTotal( - students[studentIndex].student_id - ); - - for ( - let skillIndex = 0; - skillIndex < jobApplication.job_application_skill.length; - skillIndex++ - ) { - if ( - jobApplication.job_application_skill[skillIndex] - .language_id != null - ) { - const language = await ormLa.getLanguage( - Number( - jobApplication.job_application_skill[skillIndex] - .language_id - ) - ); - if (language != null) { - jobApplication.job_application_skill[skillIndex].skill = - language.name; - } else { - return Promise.reject(errors.cookInvalidID()); - } - } - } - - studentList.push({ - student: students[studentIndex], - jobApplication: jobApplication, - evaluations: evaluations, - roles: roles, - }); - } else { - return Promise.reject(errors.cookInvalidID()); - } - } - - return Promise.resolve({ - data: studentList, - }); -} +import { checkYearPermissionStudent, errors } from "../utility"; +import { login_user, person } from "@prisma/client"; /** * Attempts to get all data for a certain student in the system. @@ -102,18 +25,28 @@ export async function getStudent( const parsedRequest = await rq.parseSingleStudentRequest(req); const checkedSessionKey = await util .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } + .then(checkYearPermissionStudent); const student = await ormSt.getStudent(checkedSessionKey.data.id); if (student == null) { return Promise.reject(errors.cookInvalidID()); } - const jobApplication = await ormJo.getLatestJobApplicationOfStudent( - student.student_id + let year; + if (checkedSessionKey.data.year === undefined) { + const latestOsocYear = await ormOs.getLatestOsoc(); + if (latestOsocYear !== null) { + year = latestOsocYear.year; + } else { + year = new Date().getFullYear(); + } + } else { + year = checkedSessionKey.data.year; + } + + const jobApplication = await ormJo.getJobApplicationByYearForStudent( + student.student_id, + year ); if (jobApplication == null) { return Promise.reject(errors.cookInvalidID()); @@ -129,8 +62,9 @@ export async function getStudent( } } - const evaluations = await ormJo.getStudentEvaluationsTotal( - student.student_id + const evaluations = await ormJo.getEvaluationsByYearForStudent( + checkedSessionKey.data.id, + year ); for (const job_application_skill of jobApplication.job_application_skill) { @@ -148,7 +82,13 @@ export async function getStudent( return Promise.resolve({ student: student, jobApplication: jobApplication, - evaluations: evaluations, + evaluation: { + evaluations: evaluations !== null ? evaluations.evaluation : [], + osoc: { + year: year, + }, + }, + evaluations: undefined, roles: roles, }); } @@ -165,14 +105,11 @@ export async function deleteStudent( return rq .parseDeleteStudentRequest(req) .then((parsed) => util.isAdmin(parsed)) + .then(checkYearPermissionStudent) .then(async (parsed) => { return ormSt - .deleteStudent(parsed.data.id) - .then(() => - ormP - .deletePersonById(parsed.data.id) - .then(() => Promise.resolve({})) - ); + .deleteStudentFromDB(parsed.data.id) + .then(() => Promise.resolve({})); }); } @@ -184,14 +121,11 @@ export async function deleteStudent( */ export async function createStudentSuggestion( req: express.Request -): Promise { +): Promise { const parsedRequest = await rq.parseSuggestStudentRequest(req); const checkedSessionKey = await util .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } + .then(checkYearPermissionStudent); const student = await ormSt.getStudent(checkedSessionKey.data.id); if (student == null) { @@ -204,6 +138,22 @@ export async function createStudentSuggestion( return Promise.reject(errors.cookNoDataError()); } + const jobApplication = await ormJo.getLatestJobApplicationOfStudent( + student.student_id + ); + + if (jobApplication == null) { + return Promise.reject(errors.cookInvalidID()); + } + + if ( + jobApplication.job_application_id !== + checkedSessionKey.data.job_application_id || + jobApplication.osoc.year !== osocYear.year + ) { + return Promise.reject(errors.cookWrongSuggestionYear()); + } + const suggestionsTotal = ( await ormJo.getStudentEvaluationsTemp(student.student_id) ).filter( @@ -211,23 +161,17 @@ export async function createStudentSuggestion( suggestion.osoc.year === osocYear.year && suggestion.evaluation.some( (evaluation) => - evaluation.login_user.login_user_id === + evaluation.login_user?.login_user_id === checkedSessionKey.userId ) ); - const jobApplication = await ormJo.getLatestJobApplicationOfStudent( - student.student_id - ); - if (jobApplication == null) { - return Promise.reject(errors.cookInvalidID()); - } - let newEvaluation; if (suggestionsTotal.length > 0) { const suggestion = suggestionsTotal[0].evaluation.filter( (evaluation) => - evaluation.login_user.login_user_id === checkedSessionKey.userId + evaluation.login_user?.login_user_id === + checkedSessionKey.userId ); newEvaluation = await ormEv.updateEvaluationForStudent({ @@ -246,19 +190,15 @@ export async function createStudentSuggestion( }); } - const loginUser = await ormLU.getLoginUserById(newEvaluation.login_user_id); - if (loginUser === null) { + let loginUser: (login_user & { person: person }) | null = null; + if (newEvaluation.login_user_id !== null) { + loginUser = await ormLU.getLoginUserById(newEvaluation.login_user_id); + } + if (loginUser === null || loginUser === undefined) { return Promise.reject(errors.cookInvalidID()); } - return Promise.resolve({ - evaluation_id: newEvaluation.evaluation_id, - senderFirstname: loginUser.person.firstname, - senderLastname: loginUser.person.lastname, - reason: newEvaluation.motivation, - decision: newEvaluation.decision, - isFinal: newEvaluation.is_final, - }); + return Promise.resolve({}); } /** @@ -269,50 +209,41 @@ export async function createStudentSuggestion( */ export async function getStudentSuggestions( req: express.Request -): Promise { +): Promise { const parsedRequest = await rq.parseGetSuggestionsStudentRequest(req); const checkedSessionKey = await util .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } + .then(checkYearPermissionStudent); const student = await ormSt.getStudent(checkedSessionKey.data.id); if (student == null) { return Promise.reject(errors.cookInvalidID()); } - const osoc = - checkedSessionKey.data.year == undefined - ? await ormOs.getLatestOsoc() - : checkedSessionKey.data.year; - if (osoc == null) { - return Promise.resolve({ - data: [], - sessionkey: checkedSessionKey.data.sessionkey, - }); - } - const suggestionsTotal = ( - await ormJo.getStudentEvaluationsTotal(student.student_id) - ).filter((suggestion) => suggestion.osoc.year === osoc.year); - - const suggestionsInfo = []; - for (const suggestion of suggestionsTotal) { - for (const evaluation of suggestion.evaluation) { - suggestionsInfo.push({ - evaluation_id: evaluation.evaluation_id, - senderFirstname: evaluation.login_user.person.firstname, - senderLastname: evaluation.login_user.person.lastname, - reason: evaluation.motivation, - decision: evaluation.decision, - isFinal: evaluation.is_final, - }); + let year; + if (checkedSessionKey.data.year === undefined) { + const latestOsocYear = await ormOs.getLatestOsoc(); + if (latestOsocYear !== null) { + year = latestOsocYear.year; + } else { + year = new Date().getFullYear(); } + } else { + year = checkedSessionKey.data.year; } + const evaluations = await ormJo.getEvaluationsByYearForStudent( + student.student_id, + year + ); + return Promise.resolve({ - data: suggestionsInfo, + evaluation: { + evaluations: evaluations !== null ? evaluations.evaluation : [], + osoc: { + year: year, + }, + }, }); } @@ -328,10 +259,7 @@ export async function createStudentConfirmation( const parsedRequest = await rq.parseFinalizeDecisionRequest(req); const checkedSessionKey = await util .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } + .then(checkYearPermissionStudent); const isAdminCheck = await util.isAdmin(parsedRequest); @@ -344,10 +272,18 @@ export async function createStudentConfirmation( const jobApplication = await ormJo.getLatestJobApplicationOfStudent( student.student_id ); + if (jobApplication == null) { return Promise.reject(errors.cookInvalidID()); } + if ( + jobApplication.job_application_id !== + checkedSessionKey.data.job_application_id + ) { + return Promise.reject(errors.cookWrongSuggestionYear()); + } + await ormEv.createEvaluationForStudent({ loginUserId: checkedSessionKey.userId, jobApplicationId: jobApplication.job_application_id, @@ -372,34 +308,44 @@ export async function filterStudents( req: express.Request ): Promise { const parsedRequest = await rq.parseFilterStudentsRequest(req); - const checkedSessionKey = await util - .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); + const checkedSessionKey = await util.checkSessionKey(parsedRequest); + + let year; + if (checkedSessionKey.data.osocYear === undefined) { + const latestOsocYear = await ormOs.getLatestOsoc(); + if (latestOsocYear !== null) { + year = latestOsocYear.year; + } else { + year = new Date().getFullYear(); + } + } else { + year = checkedSessionKey.data.osocYear; } const students = await ormSt.filterStudents( - checkedSessionKey.data.firstNameFilter, - checkedSessionKey.data.lastNameFilter, + { + currentPage: checkedSessionKey.data.currentPage, + pageSize: checkedSessionKey.data.pageSize, + }, + checkedSessionKey.data.nameFilter, checkedSessionKey.data.emailFilter, checkedSessionKey.data.roleFilter, checkedSessionKey.data.alumniFilter, checkedSessionKey.data.coachFilter, checkedSessionKey.data.statusFilter, - checkedSessionKey.data.osocYear, + year, checkedSessionKey.data.emailStatusFilter, - checkedSessionKey.data.firstNameSort, - checkedSessionKey.data.lastNameSort, + checkedSessionKey.data.nameSort, checkedSessionKey.data.emailSort, - checkedSessionKey.data.alumniSort + checkedSessionKey.userId ); - const studentlist = []; + const studentlist: InternalTypes.Student[] = []; - for (const student of students) { - const jobApplication = await ormJo.getLatestJobApplicationOfStudent( - student.student_id + for (const student of students.data) { + const jobApplication = await ormJo.getJobApplicationByYearForStudent( + student.student_id, + year ); if (jobApplication == null) { return Promise.reject(errors.cookInvalidID()); @@ -415,8 +361,9 @@ export async function filterStudents( } } - const evaluations = await ormJo.getStudentEvaluationsTotal( - student.student_id + const evaluations = await ormJo.getEvaluationsByYearForStudent( + student.student_id, + year ); for (const job_application_skill of jobApplication.job_application_skill) { @@ -434,12 +381,19 @@ export async function filterStudents( studentlist.push({ student: student, jobApplication: jobApplication, - evaluations: evaluations, + evaluation: { + evaluations: evaluations !== null ? evaluations.evaluation : [], + osoc: { + year: year, + }, + }, + evaluations: undefined, roles: roles, }); } return Promise.resolve({ + pagination: students.pagination, data: studentlist, }); } @@ -454,7 +408,7 @@ export function getRouter(): express.Router { util.setupRedirect(router, "/student"); util.route(router, "get", "/filter", filterStudents); - util.route(router, "get", "/all", listStudents); + util.route(router, "get", "/all", filterStudents); util.route(router, "get", "/:id", getStudent); util.route(router, "delete", "/:id", deleteStudent); diff --git a/backend/routes/template.ts b/backend/routes/template.ts index d2cc4da3..127dc743 100644 --- a/backend/routes/template.ts +++ b/backend/routes/template.ts @@ -5,7 +5,7 @@ import * as rq from "../request"; import { ApiError, Responses } from "../types"; import * as util from "../utility"; -const notOwnerError: ApiError = { +export const notOwnerError: ApiError = { http: util.errors.cookInsufficientRights().http, reason: "You can only modify/delete templates you own.", }; @@ -15,7 +15,7 @@ export async function getAllTemplates( ): Promise { return rq .parseTemplateListRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) + .then((parsed) => util.isAdmin(parsed)) .then(() => ormT .getAllTemplates() @@ -39,7 +39,7 @@ export async function getSingleTemplate( ): Promise { return rq .parseGetTemplateRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) + .then((parsed) => util.isAdmin(parsed)) .then((checked) => ormT .getTemplateById(checked.data.id) @@ -60,7 +60,7 @@ export async function createTemplate( ): Promise { return rq .parseNewTemplateRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) + .then((parsed) => util.isAdmin(parsed)) .then((checked) => ormT .createTemplate({ @@ -88,7 +88,7 @@ export async function updateTemplate( ): Promise { return rq .parseUpdateTemplateRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) + .then((parsed) => util.isAdmin(parsed)) .then(async (checked) => { return ormT .getTemplateById(checked.data.id) @@ -127,17 +127,14 @@ export async function deleteTemplate( ): Promise { return rq .parseDeleteTemplateRequest(req) - .then((parsed) => util.checkSessionKey(parsed)) + .then((parsed) => util.isAdmin(parsed)) .then(async (checked) => { return ormT .getTemplateById(checked.data.id) .then((templ) => util.getOrReject(templ)) .then(async (templ) => { if (templ.owner_id != checked.userId) { - return util - .isAdmin(checked.data) - .catch(() => Promise.reject(notOwnerError)) - .then(() => templ); + return Promise.reject(notOwnerError); } return Promise.resolve(templ); }) diff --git a/backend/routes/user.ts b/backend/routes/user.ts index 8de67adb..2f32a943 100644 --- a/backend/routes/user.ts +++ b/backend/routes/user.ts @@ -1,12 +1,12 @@ import { account_status_enum } from "@prisma/client"; +import * as prisma from "@prisma/client"; import express from "express"; import * as validator from "validator"; import * as ormLU from "../orm_functions/login_user"; -import * as ormL from "../orm_functions/login_user"; import * as ormP from "../orm_functions/person"; import * as rq from "../request"; -import { Responses } from "../types"; +import { AccountStatus, Responses } from "../types"; import * as util from "../utility"; import { errors } from "../utility"; import * as session_key from "./session_key.json"; @@ -15,6 +15,8 @@ import { removeAllKeysForUser, } from "../orm_functions/session_key"; import * as config from "../config.json"; +import * as bcrypt from "bcrypt"; +import * as ormLuOs from "../orm_functions/login_user_osoc"; /** * Attempts to list all students in the system. @@ -26,28 +28,29 @@ export async function listUsers( req: express.Request ): Promise { const parsedRequest = await rq.parseUserAllRequest(req); - const checkedSessionKey = await util - .isAdmin(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } - const loginUsers = await ormL.getAllLoginUsers(); - - loginUsers.map((val) => ({ - person_data: { - id: val.person.person_id, - name: val.person.firstname, - email: val.person.email, - github: val.person.github, + await util.isAdmin(parsedRequest); + // const loginUsers = await ormL.getAllLoginUsers(); + const loginUsers = await ormLU.filterLoginUsers({ + currentPage: parsedRequest.currentPage, + pageSize: parsedRequest.pageSize, + }); + + const updated = loginUsers.data.map((val) => ({ + person: { + person_id: val.person.person_id, + name: val.person.name, + email: val.person.email === null ? "" : val.person.email, + github: val.person.github === null ? "" : val.person.github, }, - coach: val.is_coach, - admin: val.is_admin, - activated: val.account_status as string, + is_coach: val.is_coach, + is_admin: val.is_admin, + account_status: val.account_status as AccountStatus, + login_user_id: val.login_user_id, })); return Promise.resolve({ - data: loginUsers, + pagination: loginUsers.pagination, + data: updated, }); } @@ -60,60 +63,69 @@ export async function listUsers( export async function createUserRequest( req: express.Request ): Promise { - return rq.parseRequestUserRequest(req).then(async (parsed) => { - if (parsed.pass == undefined) { - console.log(" -> WARNING user request without password"); - return Promise.reject(util.errors.cookArgumentError()); - } - return ormP - .createPerson({ - firstname: parsed.firstName, - lastname: "", - email: validator.default - .normalizeEmail(parsed.email) - .toString(), - }) - .then((person) => { - console.log("Created a person: " + person); - return ormLU.createLoginUser({ - personId: person.person_id, - password: parsed.pass, - isAdmin: false, - isCoach: true, - accountStatus: "PENDING", - }); - }) - .then((user) => { - const key: string = util.generateKey(); - const futureDate = new Date(); - futureDate.setDate( - futureDate.getDate() + session_key.valid_period - ); - return addSessionKey(user.login_user_id, key, futureDate); - }) - .then((user) => { - console.log("Attached a login user: " + user); - return Promise.resolve({ - id: user.login_user_id, - sessionkey: user.session_key, - }); - }) - .catch((e) => { - if ("code" in e && e.code == "P2002") { - return Promise.reject({ - http: 400, - reason: "Can't register the same email address twice.", - }); - } - return Promise.reject(e); + const parsedRequest = await rq.parseRequestUserRequest(req); + + const foundPerson = await ormP.searchPersonByLogin( + validator.default.normalizeEmail(parsedRequest.email).toString() + ); + + let person: prisma.person; + + if (foundPerson.length !== 0) { + const foundLoginUser = await ormLU.searchLoginUserByPerson( + foundPerson[0].person_id + ); + if (foundLoginUser !== null) { + return Promise.reject({ + http: 400, + reason: "Can't register the same email address twice.", }); + } + + person = await ormP.updatePerson({ + personId: foundPerson[0].person_id, + name: parsedRequest.name, + }); + } else { + person = await ormP.createPerson({ + name: parsedRequest.name, + email: validator.default + .normalizeEmail(parsedRequest.email) + .toString(), + }); + } + + const hash = await bcrypt.hash( + parsedRequest.pass, + config.encryption.encryptionRounds + ); + + const loginUser = await ormLU.createLoginUser({ + personId: person.person_id, + password: hash, + isAdmin: false, + isCoach: true, + accountStatus: "PENDING", + }); + + const key: string = util.generateKey(); + const futureDate = new Date(Date.now()); + futureDate.setDate(futureDate.getDate() + session_key.valid_period); + const addedKey = await addSessionKey( + loginUser.login_user_id, + key, + futureDate + ); + + return Promise.resolve({ + id: addedKey.login_user_id, + sessionkey: addedKey.session_key, }); } export async function setAccountStatus( person_id: number, stat: account_status_enum, - key: string, is_admin: boolean, is_coach: boolean ): Promise { @@ -130,10 +142,9 @@ export async function setAccountStatus( }) ) .then((res) => { - console.log(res.person.firstname); return Promise.resolve({ id: res.person_id, - name: res.person.firstname + " " + res.person.lastname, + name: res.person.name, }); }); } @@ -152,7 +163,7 @@ export async function createUserAcceptance( .then((parsed) => util.isAdmin(parsed)) .then((parsed) => util.mutable(parsed, parsed.data.id)) .then(async (parsed) => { - return ormL + return ormLU .searchLoginUserByPerson(parsed.data.id) .then((logUs) => { if ( @@ -162,7 +173,6 @@ export async function createUserAcceptance( return setAccountStatus( parsed.data.id, "ACTIVATED", - parsed.data.sessionkey, parsed.data.is_admin .toString() .toLowerCase() @@ -192,7 +202,7 @@ export async function deleteUserRequest( .then((parsed) => util.isAdmin(parsed)) .then((parsed) => util.mutable(parsed, parsed.data.id)) .then(async (parsed) => { - return ormL + return ormLU .searchLoginUserByPerson(parsed.data.id) .then((logUs) => { if ( @@ -202,7 +212,6 @@ export async function deleteUserRequest( return setAccountStatus( parsed.data.id, "DISABLED", - parsed.data.sessionkey, parsed.data.is_admin .toString() .toLowerCase() @@ -234,6 +243,10 @@ export async function filterUsers( .then(async (parsed) => { return ormLU .filterLoginUsers( + { + currentPage: parsed.data.currentPage, + pageSize: parsed.data.pageSize, + }, parsed.data.nameFilter, parsed.data.emailFilter, parsed.data.nameSort, @@ -243,18 +256,28 @@ export async function filterUsers( parsed.data.isAdminFilter ) .then((users) => { - users.map((val) => ({ - person_data: { - id: val.person.person_id, - name: val.person.firstname, - email: val.person.email, - github: val.person.github, + const udat = users.data.map((val) => ({ + person: { + person_id: val.person.person_id, + name: val.person.name, + email: + val.person.email === null + ? "" + : val.person.email, + github: + val.person.github === null + ? "" + : val.person.github, }, - coach: val.is_coach, - admin: val.is_admin, - activated: val.account_status as string, + is_coach: val.is_coach, + is_admin: val.is_admin, + account_status: val.account_status as AccountStatus, + login_user_id: val.login_user_id, })); - return Promise.resolve({ data: users }); + return Promise.resolve({ + data: udat, + pagination: users.pagination, + }); }); }); } @@ -269,32 +292,59 @@ export async function userModSelf( return rq .parseUserModSelfRequest(req) .then((parsed) => util.checkSessionKey(parsed, false)) - .then((checked) => { + .then(async (checked) => { return ormLU .getLoginUserById(checked.userId) .then((user) => util.getOrReject(user)) - .then((user) => { + .then(async (user) => { + // only change the password if an old and new password is given + let valid = true; if ( - checked.data.pass != undefined && - user.password != checked.data.pass.oldpass - ) - return Promise.reject(); + checked.data.pass !== null && + checked.data.pass !== undefined && + user.password !== null + ) { + valid = await bcrypt.compare( + checked.data.pass?.oldpass, + user.password + ); + } + // the old password to compare to was not as expected => return error + if (!valid) { + return Promise.reject({ + http: 409, + reason: "Old password is incorrect. Didn't update password.", + }); + } + return Promise.resolve(user); + }) + .then(async (user) => { + if ( + checked.data.pass !== null && + checked.data.pass !== undefined && + checked.data.pass.oldpass !== null && + checked.data.pass.oldpass !== undefined && + checked.data.pass.newpass !== null && + checked.data.pass.newpass !== undefined + ) { + return ormLU.updateLoginUser({ + loginUserId: checked.userId, + accountStatus: user.account_status, + password: await bcrypt.hash( + checked.data.pass?.newpass, + config.encryption.encryptionRounds + ), + }); + } return Promise.resolve(user); }) - .then((user) => - ormLU.updateLoginUser({ - loginUserId: checked.userId, - accountStatus: user.account_status, - password: checked.data.pass?.newpass, - }) - ) .then((user) => Promise.resolve(user.person)) - .then((person) => { + .then(async (person) => { if (checked.data.name != undefined) { return ormP .updatePerson({ personId: person.person_id, - firstname: checked.data.name, + name: checked.data.name, }) .then(() => Promise.resolve()); } @@ -302,7 +352,7 @@ export async function userModSelf( }) .then(() => Promise.resolve(checked)); }) - .then((checked) => { + .then(async (checked) => { if (checked.data.pass == undefined) { return Promise.resolve({ sessionkey: checked.data.sessionkey }); } @@ -332,28 +382,103 @@ export async function getCurrentUser( ): Promise { const parsedRequest = await rq.parseCurrentUserRequest(req); - const checkedSessionKey = await util - .checkSessionKey(parsedRequest) - .catch((res) => res); - if (checkedSessionKey.data == undefined) { - return Promise.reject(errors.cookInvalidID()); - } + const checkedSessionKey = await util.checkSessionKey(parsedRequest); - const login_user = await ormL + const login_user = await ormLU .getLoginUserById(checkedSessionKey.userId) .then((obj) => util.getOrReject(obj)); - login_user.password = null; - return Promise.resolve({ - data: { - login_user: login_user, + const user = { + person: { + person_id: login_user.person.person_id, + name: login_user.person.name, + email: + login_user.person.email === null ? "" : login_user.person.email, + github: + login_user.person.github === null + ? "" + : login_user.person.github, }, - sessionkey: checkedSessionKey.data.sessionkey, - }).then((obj) => { - console.log(JSON.stringify(obj)); - return Promise.resolve(obj); - }); + is_coach: login_user.is_coach, + is_admin: login_user.is_admin, + account_status: login_user.account_status as AccountStatus, + login_user_id: login_user.login_user_id, + }; + + return Promise.resolve(user); +} + +/** + * Attempts to create a user permission in the system. + * @param req The Express.js request to extract all required data from. + * @returns See the API documentation. Successes are passed using + * `Promise.resolve`, failures using `Promise.reject`. + */ +export async function createUserPermission( + req: express.Request +): Promise { + const parsedRequest = await rq.parseUsersPermissionsRequest(req); + const checkedSessionKey = await util.isAdmin(parsedRequest); + + await ormLuOs.addOsocToUser( + checkedSessionKey.data.login_user_id, + checkedSessionKey.data.osoc_id + ); + + return Promise.resolve({}); +} + +/** + * Attempts to delte a user permission in the system. + * @param req The Express.js request to extract all required data from. + * @returns See the API documentation. Successes are passed using + * `Promise.resolve`, failures using `Promise.reject`. + */ +export async function deleteUserPermission( + req: express.Request +): Promise { + const parsedRequest = await rq.parseUsersPermissionsRequest(req); + const checkedSessionKey = await util.isAdmin(parsedRequest); + + await ormLuOs.removeOsocFromUser( + checkedSessionKey.data.login_user_id, + checkedSessionKey.data.osoc_id + ); + + return Promise.resolve({}); } + +/** + * Attempts to delte a user permission in the system. + * @param req The Express.js request to extract all required data from. + * @returns See the API documentation. Successes are passed using + * `Promise.resolve`, failures using `Promise.reject`. + */ +export async function getYearPermissions( + req: express.Request +): Promise { + const parsedRequest = await rq.parseGetUserPermissionsRequest(req); + + const isAdminCheck = await util.isAdmin(parsedRequest); + + if (isAdminCheck.is_admin) { + const years = await ormLuOs.getOsocYearsForLoginUserById( + isAdminCheck.data.id + ); + + return Promise.resolve( + years.map((year) => { + return { + osoc_id: year.osoc_id, + year: year.osoc.year, + }; + }) + ); + } + + return Promise.reject(errors.cookInsufficientRights()); +} + /** * Gets the router for all `/user/` related endpoints. * @returns An Express.js {@link express.Router} routing all `/user/` @@ -369,6 +494,11 @@ export function getRouter(): express.Router { util.route(router, "get", "/self", getCurrentUser); util.route(router, "post", "/self", userModSelf); + util.route(router, "post", "/year/:id", createUserPermission); + util.route(router, "delete", "/year/:id", deleteUserPermission); + + util.route(router, "get", "/years/:id", getYearPermissions); + router.post("/request", (req, res) => util.respOrErrorNoReinject(res, createUserRequest(req)) ); diff --git a/backend/server.ts b/backend/server.ts new file mode 100644 index 00000000..98cb6380 --- /dev/null +++ b/backend/server.ts @@ -0,0 +1,64 @@ +import body from "body-parser"; +import cors from "cors"; +import express from "express"; +import path from "path"; +import * as config from "./config.json"; +import * as ep from "./endpoints"; +import * as util from "./utility"; +import { createServer } from "http"; +import { Server } from "socket.io"; +import { + ClientToServerEvents, + InterServerEvents, + ServerToClientEvents, + SocketData, +} from "./types"; +import { registerLoginUserHandlers } from "./websocket_events/login_user"; +import { registerStudentHandlers } from "./websocket_events/student"; +import { registerProjectHandlers } from "./websocket_events/project"; +import { registerOsocHandlers } from "./websocket_events/osoc"; + +export const app: express.Application = express(); +export const port: number = config.global.port; +export const httpServer = createServer(app); + +// require makes it A LOT easier to use this. Import gives some weird behaviour +// that is not easy to work around +// eslint-disable-next-line @typescript-eslint/no-var-requires +require("dotenv").config({ + path: path.join(__dirname, `./.env.${process.env.NODE_ENV}`), +}); + +const io = new Server< + ClientToServerEvents, + ServerToClientEvents, + InterServerEvents, + SocketData +>(httpServer, { + cors: { + origin: process.env.FRONTEND, + }, + path: "/socket.io", // we locate the place for websockets at `/socket.io` inside the express server +}); + +app.use(body.urlencoded({ extended: true })); +app.use(express.json()); +app.use(cors()); +app.use((req, _, next) => util.logRequest(req, next)); +app.use((req, _, next) => { + util.queryToBody(req); + next(); +}); +ep.attach(app); +config.global.homes.forEach((home) => util.addInvalidVerbs(app, home + "/")); + +/** + * install all the socket.io listeners. + * We do this by using function "register...." that contain the listeners + */ +io.on("connection", (socket) => { + registerLoginUserHandlers(io, socket); + registerStudentHandlers(io, socket); + registerProjectHandlers(io, socket); + registerOsocHandlers(io, socket); +}); diff --git a/backend/tests/database_setup.ts b/backend/tests/database_setup.ts new file mode 100644 index 00000000..468fe099 --- /dev/null +++ b/backend/tests/database_setup.ts @@ -0,0 +1,481 @@ +/* istanbul ignore file */ +import * as dbtypes from "@prisma/client"; +import prisma from "../prisma/prisma"; +import * as config from "../config.json"; +import * as bcrypt from "bcrypt"; + +export interface OGNamePass { + name: string; + pass: string; +} + +export function personData() { + return [ + { + email: "email@testmail.com", + name: "firstNameTest", + }, + { + github: "test@github.com", + name: "firstNameTest2", + }, + { + email: "testmail2@mail.com", + name: "first", + }, + { + email: "studentmail@mail.com", + name: "student", + }, + { + email: "coachmail@mail.com", + name: "coach", + }, + ]; +} + +export function loginuserData(people: dbtypes.person[]) { + return [ + { + person_id: people[0].person_id, + password: "easy_password", + is_admin: true, + is_coach: true, + account_status: "ACTIVATED" as dbtypes.account_status_enum, + }, + { + person_id: people[1].person_id, + password: "123_bad_pass", + is_admin: true, + is_coach: false, + account_status: "PENDING" as dbtypes.account_status_enum, + }, + { + person_id: people[4].person_id, + password: "Mypassword", + is_admin: true, + is_coach: true, + account_status: "ACTIVATED" as dbtypes.account_status_enum, + }, + ]; +} + +export function osocsData() { + return [ + { + year: 2022, + }, + { + year: 2023, + }, + ]; +} + +export function projectsData(osocs: dbtypes.osoc[]) { + return [ + { + name: "project-test", + osoc_id: osocs[0].osoc_id, + partner: "partner-test", + start_date: new Date("2022-05-22"), + end_date: new Date("2022-06-31"), + }, + { + name: "project-test-2", + osoc_id: osocs[1].osoc_id, + partner: "partner-test-2", + start_date: new Date("2022-09-15"), + end_date: new Date("2022-10-23"), + }, + { + name: "project-test-3", + osoc_id: osocs[1].osoc_id, + partner: "partner-test-3", + start_date: new Date("2022-09-15"), + end_date: new Date("2022-10-23"), + }, + ]; +} + +export function studentsData(people: dbtypes.person[]) { + return [ + { + person_id: people[2].person_id, + gender: "Male", + pronouns: "He/ Him", + phone_number: "112", + alumni: false, + }, + { + person_id: people[1].person_id, + gender: "Female", + pronouns: "She/ Her", + phone_number: "107", + alumni: true, + }, + { + person_id: people[3].person_id, + gender: "Female", + pronouns: "She/ Her", + phone_number: "111", + alumni: false, + }, + ]; +} + +export function jobApplicationsData( + students: dbtypes.student[], + osocs: dbtypes.osoc[] +) { + return [ + { + student_id: students[0].student_id, + student_volunteer_info: "no volunteer", + responsibilities: "no responsibilities", + fun_fact: "this is a fun fact", + student_coach: false, + osoc_id: osocs[0].osoc_id, + edus: ["basic education"], + edu_level: "higher education", + edu_duration: 5, + edu_institute: "Ugent", + edu_year: "4", + email_status: dbtypes.email_status_enum.APPLIED, + created_at: new Date("December 17, 2021 14:24:00"), + }, + { + student_id: students[0].student_id, + student_volunteer_info: "I'd like to volunteer", + responsibilities: "no responsibilities2", + fun_fact: "this is a fun fact too", + student_coach: true, + osoc_id: osocs[0].osoc_id, + edus: ["higher education"], + edu_level: "MaNaMa", + edu_duration: 8, + edu_institute: "Ugent", + edu_year: "7", + email_status: dbtypes.email_status_enum.APPROVED, + created_at: new Date("December 20, 2021 03:24:00"), + }, + { + student_id: students[2].student_id, + student_volunteer_info: "no volunteer", + responsibilities: "no responsibilities", + fun_fact: "this is a fun fact", + student_coach: false, + osoc_id: osocs[0].osoc_id, + edus: ["something something"], + edu_level: "higher education", + edu_duration: 5, + edu_institute: "Ugent", + edu_year: "3", + email_status: dbtypes.email_status_enum.APPLIED, + created_at: new Date("December 25, 2021 14:24:00"), + }, + { + student_id: students[2].student_id, + student_volunteer_info: "I'd like to volunteer", + responsibilities: "no responsibilities2", + fun_fact: "this is a fun fact too", + student_coach: true, + osoc_id: osocs[1].osoc_id, + edus: ["higher education"], + edu_level: "MaNaMa", + edu_duration: 8, + edu_institute: "Ugent", + edu_year: "3", + email_status: dbtypes.email_status_enum.APPROVED, + created_at: new Date("December 31, 2021 03:24:00"), + }, + ]; +} + +export function evaluationsData( + users: dbtypes.login_user[], + applics: dbtypes.job_application[] +) { + return [ + { + login_user_id: users[0].login_user_id, + job_application_id: applics[0].job_application_id, + decision: dbtypes.decision_enum.MAYBE, + motivation: "low education level", + is_final: false, + }, + { + login_user_id: users[0].login_user_id, + job_application_id: applics[0].job_application_id, + decision: dbtypes.decision_enum.YES, + motivation: "awesome job application", + is_final: true, + }, + ]; +} + +export function rolesData() { + return [ + { + name: "Developer", + }, + { + name: "Marketeer", + }, + { + name: "Frontend", + }, + { + name: "Backend", + }, + ]; +} + +export function projectRolesData(project: dbtypes.project, role: dbtypes.role) { + return [ + { + project_id: project.project_id, + role_id: role.role_id, + positions: 3, + }, + { + project_id: project.project_id, + role_id: role.role_id, + positions: 1, + }, + ]; +} + +export function appliedRolesData( + applics: dbtypes.job_application[], + roles: dbtypes.role[] +) { + return [ + { + job_application_id: applics[0].job_application_id, + role_id: roles[2].role_id, + }, + { + job_application_id: applics[1].job_application_id, + role_id: roles[2].role_id, + }, + { + job_application_id: applics[1].job_application_id, + role_id: roles[3].role_id, + }, + ]; +} + +export function langaugesData() { + return [ + { + name: "Dutch", + }, + { + name: "French", + }, + ]; +} + +export function attachmentsData(applics: dbtypes.job_application[]) { + return [ + { + job_application_id: applics[1].job_application_id, + data: ["test-cv-link.com"], + type: ["CV_URL"] as dbtypes.type_enum[], + }, + { + job_application_id: applics[1].job_application_id, + data: ["test-portfolio-link.com"], + type: ["PORTFOLIO_URL"] as dbtypes.type_enum[], + }, + ]; +} + +export function applicSkillsData( + applics: dbtypes.job_application[], + langs: dbtypes.language[] +) { + return [ + { + job_application_id: applics[1].job_application_id, + skill: "SQL", + language_id: langs[0].language_id, + level: 5, + is_preferred: false, + is_best: true, + }, + { + job_application_id: applics[0].job_application_id, + skill: "Python", + language_id: langs[0].language_id, + level: 4, + is_preferred: false, + is_best: false, + }, + ]; +} + +export function sessionKeyData(users: dbtypes.login_user[]) { + const futureDate = new Date(Date.now()); // it's easier to mock Date.now + futureDate.setDate(futureDate.getDate() + 15); + return [ + { + login_user_id: users[0].login_user_id, + session_key: "key", + valid_until: futureDate, + }, + { + login_user_id: users[0].login_user_id, + session_key: "key2", + valid_until: futureDate, + }, + ]; +} + +export function passResetsData(users: dbtypes.login_user[]) { + return [ + { + login_user_id: users[2].login_user_id, + reset_id: "5444024611562312170969914212450321", + valid_until: new Date("2022-07-13"), + }, + ]; +} + +export async function hashAllPasswords(): Promise { + const users = await prisma.login_user.findMany({ + include: { person: true }, + }); + const ogs = users.map((x) => ({ name: x.person.email, pass: x.password })); + + await Promise.all( + users.map(async (user) => { + if (user.password == null) return; + const newpass = await bcrypt.hash( + user.password, + config.encryption.encryptionRounds + ); + await prisma.login_user.update({ + where: { login_user_id: user.login_user_id }, + data: { password: newpass }, + }); + }) + ); + + return ogs.flatMap((x) => { + const xn = x.name; + const xp = x.pass; // trick ts compiler + if (xn != null && xp != null) return [{ name: xn, pass: xp }]; + return []; + }); +} + +export async function teardown() { + await prisma.$transaction([ + prisma.password_reset.deleteMany(), + prisma.job_application_skill.deleteMany(), + prisma.language.deleteMany(), + prisma.attachment.deleteMany(), + prisma.applied_role.deleteMany(), + prisma.evaluation.deleteMany(), + prisma.job_application.deleteMany(), + prisma.session_keys.deleteMany(), + prisma.project_user.deleteMany(), + prisma.contract.deleteMany(), + prisma.project_role.deleteMany(), + prisma.project.deleteMany(), + prisma.osoc.deleteMany(), + prisma.student.deleteMany(), + prisma.login_user.deleteMany(), + prisma.role.deleteMany(), + prisma.person.deleteMany(), + ]); +} + +export async function setup(cleanFirst: boolean) { + if (cleanFirst) await teardown(); + + // create persons + await prisma.person.createMany({ + data: personData(), + }); + const persons = await prisma.person.findMany(); + + // create login users + await prisma.login_user.createMany({ + data: loginuserData(persons), + }); + const login_users = await prisma.login_user.findMany(); + + // create osoc editions + await prisma.osoc.createMany({ + data: osocsData(), + }); + const osocs = await prisma.osoc.findMany(); + + // create projects + await prisma.project.createMany({ + data: projectsData(osocs), + }); + + await prisma.student.createMany({ + data: studentsData(persons), + }); + const students = await prisma.student.findMany(); + + // create job applications + await prisma.job_application.createMany({ + data: jobApplicationsData(students, osocs), + }); + + const job_applications = await prisma.job_application.findMany(); + + // create evaluations + await prisma.evaluation.createMany({ + data: evaluationsData(login_users, job_applications), + }); + + // create roles + await prisma.role.createMany({ + data: rolesData(), + }); + + const project = await prisma.project.findFirst(); + const role = await prisma.role.findFirst(); + if (project && role) { + // create roles + await prisma.project_role.createMany({ + data: projectRolesData(project, role), + }); + } + const roles = await prisma.role.findMany(); + await prisma.applied_role.createMany({ + data: appliedRolesData(job_applications, roles), + }); + + // create languages + await prisma.language.createMany({ + data: langaugesData(), + }); + + // create attachments + await prisma.attachment.createMany({ + data: attachmentsData(job_applications), + }); + + const languages = await prisma.language.findMany(); + // create job application skills + await prisma.job_application_skill.createMany({ + data: applicSkillsData(job_applications, languages), + }); + + // create session keys + await prisma.session_keys.createMany({ + data: sessionKeyData(login_users), + }); + + // create password reset + await prisma.password_reset.createMany({ + data: passResetsData(login_users), + }); +} diff --git a/backend/tests/integration_setup.ts b/backend/tests/integration_setup.ts new file mode 100644 index 00000000..ec01f9c6 --- /dev/null +++ b/backend/tests/integration_setup.ts @@ -0,0 +1,6 @@ +import * as db from "./database_setup"; + +/* istanbul ignore file */ + +beforeAll(async () => await db.setup(false)); +afterAll(async () => await db.teardown()); diff --git a/backend/tests/jest_sequencer.js b/backend/tests/jest_sequencer.js new file mode 100644 index 00000000..60aa81e4 --- /dev/null +++ b/backend/tests/jest_sequencer.js @@ -0,0 +1,26 @@ +const TestSequencer = require('@jest/test-sequencer').default; + +const directories = { + 'tests': 0, + 'orm_unit': 1, + 'orm_integration': 2, + 'routes_unit': 3, + 'routes_integration': 4 +}; + +class SortByDir extends TestSequencer { + sort(tests) { + return tests.map(x => { + const tmp = x.path.split('/'); + return { test: x, dir: directories[tmp[tmp.length - 2]], fl: tmp[tmp.length - 1] }; + }).sort((one, other) => { + const dirOrder = one.dir - other.dir; + if(dirOrder == 0) { + return one.fl.localeCompare(other.fl, 'en'); + } + return dirOrder; + }).map(x => x.test); + } +} + +module.exports = SortByDir; diff --git a/backend/tests/mocking/mocks.ts b/backend/tests/mocking/mocks.ts index 55b7ab11..9abf088c 100644 --- a/backend/tests/mocking/mocks.ts +++ b/backend/tests/mocking/mocks.ts @@ -1,8 +1,10 @@ +/* istanbul ignore file */ + import CallableInstance from "callable-instance"; import express from "express"; import core from "express-serve-static-core"; import { setTimeout } from "timers/promises"; - +/* istanbul ignore file */ // jest should ignore this file for coverage and testing because it is just setup type Call = ( req: express.Request, res: express.Response, @@ -151,7 +153,6 @@ export class MockedRouter if (cb == undefined) { throw getInvalidVerbEndpointError(verb, ep); } else { - console.log("[mockedRouter]: returning await..."); return await Promise.resolve().then( async () => await cb(req, res, function () { diff --git a/backend/tests/orm_integration/applied_role.test.ts b/backend/tests/orm_integration/applied_role.test.ts index 6a847d29..61d76fd5 100644 --- a/backend/tests/orm_integration/applied_role.test.ts +++ b/backend/tests/orm_integration/applied_role.test.ts @@ -1,6 +1,8 @@ import prisma from "../../prisma/prisma"; import { deleteAppliedRolesByJobApplication } from "../../orm_functions/applied_role"; +import "../integration_setup"; + it("should delete the applied roles for the job application", async () => { const [job_applications, roles] = await Promise.all([ prisma.job_application.findMany(), diff --git a/backend/tests/orm_integration/attachment.test.ts b/backend/tests/orm_integration/attachment.test.ts index 0563ec9c..2e4f89c8 100644 --- a/backend/tests/orm_integration/attachment.test.ts +++ b/backend/tests/orm_integration/attachment.test.ts @@ -21,6 +21,8 @@ const attachment2 = { type: ["PORTFOLIO_URL"], }; +import "../integration_setup"; + it("should create 1 new attachment linked to a job application", async () => { const job_application = await prisma.job_application.findFirst(); if (job_application) { diff --git a/backend/tests/orm_integration/contract.test.ts b/backend/tests/orm_integration/contract.test.ts index 5e12cf7c..051391d0 100644 --- a/backend/tests/orm_integration/contract.test.ts +++ b/backend/tests/orm_integration/contract.test.ts @@ -11,6 +11,8 @@ import { import { CreateContract, UpdateContract } from "../../orm_functions/orm_types"; import { contract_status_enum } from "@prisma/client"; +import "../integration_setup"; + const contract1: UpdateContract = { contractId: 0, information: "Contract details", @@ -40,8 +42,12 @@ it("should create 1 new contract linked to a student", async () => { const created_contract = await createContract(contract); contract1.contractId = created_contract.contract_id; contract2.contractId = created_contract.contract_id; - contract1.loginUserId = created_contract.created_by_login_user_id; - contract2.loginUserId = created_contract.created_by_login_user_id; + if (created_contract.created_by_login_user_id) { + contract1.loginUserId = created_contract.created_by_login_user_id; + } + if (created_contract.created_by_login_user_id) { + contract2.loginUserId = created_contract.created_by_login_user_id; + } expect(created_contract).toHaveProperty( "contract_id", contract1.contractId diff --git a/backend/tests/orm_integration/evaluation.test.ts b/backend/tests/orm_integration/evaluation.test.ts index 434d26a6..bead59b6 100644 --- a/backend/tests/orm_integration/evaluation.test.ts +++ b/backend/tests/orm_integration/evaluation.test.ts @@ -7,10 +7,14 @@ import { checkIfFinalEvaluationExists, updateEvaluationForStudent, getLoginUserByEvaluationId, + getEvaluationByPartiesFor, + deleteEvaluationsByJobApplication, } from "../../orm_functions/evaluation"; import prisma from "../../prisma/prisma"; import { decision_enum } from "@prisma/client"; +import "../integration_setup"; + const evaluation1: UpdateEvaluationForStudent = { evaluation_id: 1, loginUserId: 1, @@ -118,3 +122,29 @@ it("should update evaluation based upon evaluation id", async () => { createdEvaluation.isFinal ); }); + +it("should return all evaluations created by a user for a student in an osoc edition", async () => { + const evaluations = await getEvaluationByPartiesFor(1, 1, 1); + for (const evaluation of evaluations) { + expect(evaluation).toHaveProperty("decision", evaluation.decision); + expect(evaluation).toHaveProperty("motivation", evaluation.motivation); + expect(evaluation).toHaveProperty("is_final", evaluation.is_final); + expect(evaluation).toHaveProperty( + "evaluation_id", + evaluation.evaluation_id + ); + expect(evaluation).toHaveProperty( + "job_application_id", + evaluation.job_application_id + ); + expect(evaluation).toHaveProperty( + "login_user_id", + evaluation.login_user_id + ); + } +}); + +it("should delete evaluations by a job application", async () => { + const numberOfDeletions = await deleteEvaluationsByJobApplication(1); + expect(numberOfDeletions).toHaveProperty("count", numberOfDeletions.count); +}); diff --git a/backend/tests/orm_integration/integration_setup.ts b/backend/tests/orm_integration/integration_setup.ts deleted file mode 100644 index 00d8db70..00000000 --- a/backend/tests/orm_integration/integration_setup.ts +++ /dev/null @@ -1,401 +0,0 @@ -import prisma from "../../prisma/prisma"; -import { decision_enum, email_status_enum } from "@prisma/client"; - -beforeAll(async () => { - // create persons - await prisma.person.createMany({ - data: [ - { - email: "email@testmail.com", - firstname: "firstNameTest", - lastname: "lastNameTest", - }, - { - github: "test@github.com", - firstname: "firstNameTest2", - lastname: "lastNameTest2", - }, - { - email: "testmail2@mail.com", - firstname: "first", - lastname: "last", - }, - { - email: "studentmail@mail.com", - firstname: "student", - lastname: "student", - }, - { - email: "coachmail@mail.com", - firstname: "coach", - lastname: "testcoach", - }, - ], - }); - const persons = await prisma.person.findMany(); - - // create login users - await prisma.login_user.createMany({ - data: [ - { - person_id: persons[0].person_id, - password: "easy_password", - is_admin: true, - is_coach: true, - account_status: "ACTIVATED", - }, - { - person_id: persons[1].person_id, - password: "123_bad_pass", - is_admin: true, - is_coach: false, - account_status: "PENDING", - }, - { - person_id: persons[4].person_id, - password: "Mypassword", - is_admin: true, - is_coach: true, - account_status: "ACTIVATED", - }, - ], - }); - - const login_users = await prisma.login_user.findMany(); - - // create osoc editions - await prisma.osoc.createMany({ - data: [ - { - year: 2022, - }, - { - year: 2023, - }, - ], - }); - const osocs = await prisma.osoc.findMany(); - - // create projects - await prisma.project.createMany({ - data: [ - { - name: "project-test", - osoc_id: osocs[0].osoc_id, - partner: "partner-test", - start_date: new Date("2022-05-22"), - end_date: new Date("2022-06-31"), - positions: 10, - }, - { - name: "project-test-2", - osoc_id: osocs[1].osoc_id, - partner: "partner-test-2", - start_date: new Date("2022-09-15"), - end_date: new Date("2022-10-23"), - positions: 9, - }, - { - name: "project-test-3", - osoc_id: osocs[1].osoc_id, - partner: "partner-test-3", - start_date: new Date("2022-09-15"), - end_date: new Date("2022-10-23"), - positions: 9, - }, - ], - }); - - await prisma.student.createMany({ - data: [ - { - person_id: persons[2].person_id, - gender: "Male", - pronouns: "He/ Him", - phone_number: "112", - alumni: false, - }, - { - person_id: persons[1].person_id, - gender: "Female", - pronouns: "She/ Her", - phone_number: "107", - alumni: true, - }, - { - person_id: persons[3].person_id, - gender: "Female", - pronouns: "She/ Her", - phone_number: "111", - alumni: false, - }, - ], - }); - const students = await prisma.student.findMany(); - - // create job applications - await prisma.job_application.createMany({ - data: [ - { - student_id: students[0].student_id, - student_volunteer_info: "no volunteer", - responsibilities: "no responsibilities", - fun_fact: "this is a fun fact", - student_coach: false, - osoc_id: osocs[0].osoc_id, - edus: ["basic education"], - edu_level: "higher education", - edu_duration: 5, - edu_institute: "Ugent", - edu_year: "4", - email_status: email_status_enum.DRAFT, - created_at: new Date("December 17, 2021 14:24:00"), - }, - { - student_id: students[0].student_id, - student_volunteer_info: "I'd like to volunteer", - responsibilities: "no responsibilities2", - fun_fact: "this is a fun fact too", - student_coach: true, - osoc_id: osocs[0].osoc_id, - edus: ["higher education"], - edu_level: "MaNaMa", - edu_duration: 8, - edu_institute: "Ugent", - edu_year: "7", - email_status: email_status_enum.SENT, - created_at: new Date("December 20, 2021 03:24:00"), - }, - { - student_id: students[2].student_id, - student_volunteer_info: "no volunteer", - responsibilities: "no responsibilities", - fun_fact: "this is a fun fact", - student_coach: false, - osoc_id: osocs[0].osoc_id, - edus: ["something something"], - edu_level: "higher education", - edu_duration: 5, - edu_institute: "Ugent", - edu_year: "3", - email_status: email_status_enum.DRAFT, - created_at: new Date("December 25, 2021 14:24:00"), - }, - { - student_id: students[2].student_id, - student_volunteer_info: "I'd like to volunteer", - responsibilities: "no responsibilities2", - fun_fact: "this is a fun fact too", - student_coach: true, - osoc_id: osocs[1].osoc_id, - edus: ["higher education"], - edu_level: "MaNaMa", - edu_duration: 8, - edu_institute: "Ugent", - edu_year: "3", - email_status: email_status_enum.SENT, - created_at: new Date("December 31, 2021 03:24:00"), - }, - ], - }); - - const job_applications = await prisma.job_application.findMany(); - - // create evaluations - await prisma.evaluation.createMany({ - data: [ - { - login_user_id: login_users[0].login_user_id, - job_application_id: job_applications[0].job_application_id, - decision: decision_enum.MAYBE, - motivation: "low education level", - is_final: false, - }, - { - login_user_id: login_users[0].login_user_id, - job_application_id: job_applications[0].job_application_id, - decision: decision_enum.YES, - motivation: "awesome job application", - is_final: true, - }, - ], - }); - - // create roles - await prisma.role.createMany({ - data: [ - { - name: "Developer", - }, - { - name: "Marketeer", - }, - { - name: "Frontend", - }, - { - name: "Backend", - }, - ], - }); - - const projects = await prisma.project.findFirst(); - const role = await prisma.role.findFirst(); - if (projects && role) { - // create roles - await prisma.project_role.createMany({ - data: [ - { - project_id: projects.project_id, - role_id: role.role_id, - positions: 3, - }, - { - project_id: projects.project_id, - role_id: role.role_id, - positions: 1, - }, - ], - }); - } - const roles = await prisma.role.findMany(); - await prisma.applied_role.createMany({ - data: [ - { - job_application_id: job_applications[0].job_application_id, - role_id: roles[2].role_id, - }, - { - job_application_id: job_applications[1].job_application_id, - role_id: roles[2].role_id, - }, - { - job_application_id: job_applications[1].job_application_id, - role_id: roles[3].role_id, - }, - ], - }); - - // create languages - await prisma.language.createMany({ - data: [ - { - name: "Dutch", - }, - { - name: "French", - }, - ], - }); - - // create attachments - await prisma.attachment.createMany({ - data: [ - { - job_application_id: job_applications[1].job_application_id, - data: ["test-cv-link.com"], - type: ["CV_URL"], - }, - { - job_application_id: job_applications[1].job_application_id, - data: ["test-portfolio-link.com"], - type: ["PORTFOLIO_URL"], - }, - ], - }); - - const languages = await prisma.language.findMany(); - // create job application skills - await prisma.job_application_skill.createMany({ - data: [ - { - job_application_id: job_applications[1].job_application_id, - skill: "SQL", - language_id: languages[0].language_id, - level: 5, - is_preferred: false, - is_best: true, - }, - { - job_application_id: job_applications[0].job_application_id, - skill: "Python", - language_id: languages[0].language_id, - level: 4, - is_preferred: false, - is_best: false, - }, - ], - }); - - // create session keys - const futureDate = new Date(); - futureDate.setDate(futureDate.getDate() + 15); - await prisma.session_keys.createMany({ - data: [ - { - login_user_id: login_users[0].login_user_id, - session_key: "key", - valid_until: futureDate, - }, - { - login_user_id: login_users[0].login_user_id, - session_key: "key2", - valid_until: futureDate, - }, - ], - }); - - // create password reset - await prisma.password_reset.createMany({ - data: [ - { - login_user_id: login_users[2].login_user_id, - reset_id: "5444024611562312170969914212450321", - valid_until: new Date("2022-07-13"), - }, - ], - }); -}); - -afterAll(async () => { - const deletePasswordReset = prisma.password_reset.deleteMany(); - const deleteJobApplicationSkillDetails = - prisma.job_application_skill.deleteMany(); - const deleteLanguageDetails = prisma.language.deleteMany(); - const deleteAttachmentDetails = prisma.attachment.deleteMany(); - const deleteAppliedRoleDetails = prisma.applied_role.deleteMany(); - const deleteEvaluationDetails = prisma.evaluation.deleteMany(); - const deleteApplicationDetails = prisma.job_application.deleteMany(); - const deleteSessionKeysDetails = prisma.session_keys.deleteMany(); - const deleteProjectUserDetails = prisma.project_user.deleteMany(); - const deleteContractDetails = prisma.contract.deleteMany(); - const deleteProjectRoleDetails = prisma.project_role.deleteMany(); - const deleteProjectDetails = prisma.project.deleteMany(); - const deleteOsocDetails = prisma.osoc.deleteMany(); - const deleteStudentDetails = prisma.student.deleteMany(); - const deleteLoginUserDetails = prisma.login_user.deleteMany(); - const deleteRoleDetails = prisma.role.deleteMany(); - const deletePersonDetails = prisma.person.deleteMany(); - - await prisma.$transaction([ - deletePasswordReset, - deleteJobApplicationSkillDetails, - deleteLanguageDetails, - deleteAttachmentDetails, - deleteAppliedRoleDetails, - deleteEvaluationDetails, - deleteApplicationDetails, - deleteSessionKeysDetails, - deleteProjectUserDetails, - deleteContractDetails, - deleteProjectRoleDetails, - deleteProjectDetails, - deleteRoleDetails, - deleteOsocDetails, - deleteStudentDetails, - deleteLoginUserDetails, - deletePersonDetails, - ]); - - await prisma.$disconnect(); -}); diff --git a/backend/tests/orm_integration/job_application.test.ts b/backend/tests/orm_integration/job_application.test.ts index b7ae3b63..63103bea 100644 --- a/backend/tests/orm_integration/job_application.test.ts +++ b/backend/tests/orm_integration/job_application.test.ts @@ -6,15 +6,17 @@ import { getJobApplication, getJobApplicationByYear, getLatestApplicationRolesForStudent, - getLatestJobApplicationOfStudent, getStudentEvaluationsFinal, getStudentEvaluationsTemp, getStudentEvaluationsTotal, + getEvaluationsByYearForStudent, } from "../../orm_functions/job_application"; import prisma from "../../prisma/prisma"; import { decision_enum, email_status_enum } from "@prisma/client"; import { CreateJobApplication } from "../../orm_functions/orm_types"; +import "../integration_setup"; + /** * aid function to compare most fields of the expected job application and the found job application * @param expected the application we expect as response from the database @@ -23,7 +25,7 @@ import { CreateJobApplication } from "../../orm_functions/orm_types"; function job_application_check( expected: { job_application_id?: number; - student_id: number; + student_id: number | null; student_volunteer_info: string; responsibilities: string | null; fun_fact: string | null; @@ -36,10 +38,10 @@ function job_application_check( edu_year: string | null; created_at: Date; email_status: email_status_enum; - }, + } | null, found: { job_application_id: number; - student_id: number; + student_id: number | null; student_volunteer_info: string; responsibilities: string | null; fun_fact: string | null; @@ -54,6 +56,18 @@ function job_application_check( email_status: email_status_enum; } ) { + if (expected == null) { + expect("SHOULD NOT BE NULL").toBeFalsy(); // fail! + return; + } + if (found.student_id == null) { + expect("FOUND STUDENT ID SHOULD NOT BE NULL").toBeFalsy(); // fail! + return; + } + if (expected.student_id == null) { + expect("EXPECTED STUDENT ID SHOULD NOT BE NULL").toBeFalsy(); // fail! + return; + } expect(found).toHaveProperty("student_id", expected.student_id); expect(found).toHaveProperty( "student_volunteer_info", @@ -115,19 +129,16 @@ it("should return all student evaluations for the student with given id", async expect(found_eval.evaluation[i].login_user).toHaveProperty( "login_user_id" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( - "firstname" + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( + "name" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( - "lastname" - ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "person_id" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "github" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "email" ); } @@ -168,19 +179,16 @@ it("should return all final student evaluations for the student with given id", expect(found_eval.evaluation[i].login_user).toHaveProperty( "login_user_id" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( - "firstname" - ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( - "lastname" + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( + "name" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "person_id" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "github" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "email" ); } @@ -222,19 +230,16 @@ it("should return all suggestion evaluations for the student with given id", asy expect(found_eval.evaluation[i].login_user).toHaveProperty( "login_user_id" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( - "firstname" + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( + "name" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( - "lastname" - ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "person_id" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "github" ); - expect(found_eval.evaluation[i].login_user.person).toHaveProperty( + expect(found_eval.evaluation[i].login_user?.person).toHaveProperty( "email" ); } @@ -281,7 +286,7 @@ it("should delete all the job applications of the given student", async () => { edu_duration: 5, edu_institute: "Ugent", edu_year: "3", - email_status: email_status_enum.DRAFT, + email_status: email_status_enum.APPLIED, created_at: new Date("December 25, 2021 14:24:00"), }, { @@ -296,7 +301,7 @@ it("should delete all the job applications of the given student", async () => { edu_duration: 8, edu_institute: "Ugent", edu_year: "3", - email_status: email_status_enum.SENT, + email_status: email_status_enum.APPROVED, created_at: new Date("December 31, 2021 03:24:00"), }, ]; @@ -331,52 +336,21 @@ it("should update the email status of the job application", async () => { edu_duration: 5, edu_institute: "Ugent", edu_year: "3", - email_status: email_status_enum.DRAFT, + email_status: email_status_enum.APPLIED, created_at: new Date("December 25, 2021 14:24:00"), }; const changed = await changeEmailStatusOfJobApplication( applics[2].job_application_id, - email_status_enum.SENT + email_status_enum.APPROVED ); job_application_check(applic, changed); - expect(changed).toHaveProperty("email_status", email_status_enum.SENT); + expect(changed).toHaveProperty("email_status", email_status_enum.APPROVED); expect(changed).toHaveProperty( "job_application_id", applics[2].job_application_id ); }); -it("should delete the job application", async () => { - const [students, osocs, applics] = await Promise.all([ - prisma.student.findMany(), - prisma.osoc.findMany(), - prisma.job_application.findMany(), - ]); - - const app = { - student_id: students[2].student_id, - student_volunteer_info: "no volunteer", - responsibilities: "no responsibilities", - fun_fact: "this is a fun fact", - student_coach: false, - osoc_id: osocs[0].osoc_id, - edus: ["something something"], - edu_level: "higher education", - edu_duration: 5, - edu_institute: "Ugent", - edu_year: "3", - email_status: email_status_enum.SENT, - created_at: new Date("December 25, 2021 14:24:00"), - }; - - const deleted = await deleteJobApplication(applics[3].job_application_id); - job_application_check(app, deleted); - expect(deleted).toHaveProperty("email_status", app.email_status); - await prisma.job_application.create({ - data: app, - }); -}); - it("should create a new job_application", async () => { const [students, osocs] = await Promise.all([ prisma.student.findMany(), @@ -395,7 +369,7 @@ it("should create a new job_application", async () => { edu_duration: 3, edu_institute: "Hogent", edu_year: "2", - email_status: email_status_enum.DRAFT, + email_status: email_status_enum.APPLIED, created_at: new Date("January 2, 2022 14:24:00"), }; @@ -411,7 +385,7 @@ it("should create a new job_application", async () => { eduDuration: 3, eduInstitute: "Hogent", eduYear: "2", - emailStatus: email_status_enum.DRAFT, + emailStatus: email_status_enum.APPLIED, createdAt: "January 2, 2022 14:24:00", }; @@ -448,45 +422,6 @@ function getDataAssociatedWithApplication( ]); } -it("should return the most recent job application of a student", async () => { - const [students, osocs] = await Promise.all([ - prisma.student.findMany(), - prisma.osoc.findMany(), - ]); - - const expected = { - student_id: students[0].student_id, - student_volunteer_info: "I'd like to volunteer", - responsibilities: "no responsibilities2", - fun_fact: "this is a fun fact too", - student_coach: true, - osoc_id: osocs[0].osoc_id, - edus: ["higher education"], - edu_level: "MaNaMa", - edu_duration: 8, - edu_institute: "Ugent", - edu_year: "7", - email_status: email_status_enum.SENT, - created_at: new Date("December 20, 2021 03:24:00"), - }; - - const found = await getLatestJobApplicationOfStudent(expected.student_id); - - const [attachments, applied_roles, job_application_skill] = - await getDataAssociatedWithApplication(found?.job_application_id); - - if (found) { - job_application_check(expected, found); - } - expect(found).toHaveProperty("email_status", expected.email_status); - expect(found).toHaveProperty("attachment", attachments); - expect(found).toHaveProperty( - "job_application_skill", - job_application_skill - ); - expect(found).toHaveProperty("applied_role", applied_roles); -}); - it("should return the job application", async () => { const applications = await prisma.job_application.findMany(); @@ -525,3 +460,16 @@ it("should return all job applications of a year", async () => { // only 3 applications for the given osoc edition expect(found.length).toEqual(3); }); + +it("should return the job application of a student in the (specified) year", async () => { + const found = await getEvaluationsByYearForStudent(1, 2022); + + if (found !== null) { + found.evaluation.forEach((ev) => { + expect(ev).toHaveProperty("decision"); + expect(ev).toHaveProperty("evaluation_id"); + expect(ev).toHaveProperty("is_final"); + expect(ev).toHaveProperty("motivation"); + }); + } +}); diff --git a/backend/tests/orm_integration/job_application_skill.test.ts b/backend/tests/orm_integration/job_application_skill.test.ts index 7ddabcce..ef797fd5 100644 --- a/backend/tests/orm_integration/job_application_skill.test.ts +++ b/backend/tests/orm_integration/job_application_skill.test.ts @@ -33,6 +33,8 @@ const jobApplicationSkill2: UpdateJobApplicationSkill = { is_best: true, }; +import "../integration_setup"; + it("should create 1 new job application skill", async () => { const job_application = await prisma.job_application.findFirst(); const language = await prisma.language.findFirst(); diff --git a/backend/tests/orm_integration/language.test.ts b/backend/tests/orm_integration/language.test.ts index a0983e9a..299eec24 100644 --- a/backend/tests/orm_integration/language.test.ts +++ b/backend/tests/orm_integration/language.test.ts @@ -19,6 +19,8 @@ const language2: UpdateLanguage = { name: "German", }; +import "../integration_setup"; + it("should create 1 new language with", async () => { const created_language = await createLanguage("English"); language1.languageId = created_language.language_id; diff --git a/backend/tests/orm_integration/login_user.test.ts b/backend/tests/orm_integration/login_user.test.ts index eff2edd2..2d9fb135 100644 --- a/backend/tests/orm_integration/login_user.test.ts +++ b/backend/tests/orm_integration/login_user.test.ts @@ -37,11 +37,12 @@ let login_user_update: UpdateLoginUser = { accountStatus: "ACTIVATED", }; +import "../integration_setup"; + it("should create 1 new login user", async () => { const person0: CreatePerson = { email: "login_user@email.be", - firstname: "login_firstname", - lastname: "login_lastname", + name: "login_name", }; const created_person = await createPerson(person0); diff --git a/backend/tests/orm_integration/osoc.test.ts b/backend/tests/orm_integration/osoc.test.ts index 2edc4270..e1e3f012 100644 --- a/backend/tests/orm_integration/osoc.test.ts +++ b/backend/tests/orm_integration/osoc.test.ts @@ -11,6 +11,8 @@ import { } from "../../orm_functions/osoc"; import prisma from "../../prisma/prisma"; +import "../integration_setup"; + it("should create a new osoc edition", async () => { const newOsoc = await createOsoc(2024); expect(newOsoc).toHaveProperty("year", 2024); diff --git a/backend/tests/orm_integration/password_reset.test.ts b/backend/tests/orm_integration/password_reset.test.ts index 735b9233..97df789d 100644 --- a/backend/tests/orm_integration/password_reset.test.ts +++ b/backend/tests/orm_integration/password_reset.test.ts @@ -9,6 +9,8 @@ import { const newReset = "5444024619724212170969914212450321"; const date = new Date("2022-07-13"); +import "../integration_setup"; + it("should create a new password resety for the given login user", async () => { const loginUser = await prisma.login_user.findFirst(); diff --git a/backend/tests/orm_integration/person.test.ts b/backend/tests/orm_integration/person.test.ts index 3765d26c..2a006177 100644 --- a/backend/tests/orm_integration/person.test.ts +++ b/backend/tests/orm_integration/person.test.ts @@ -10,54 +10,48 @@ import { const person4: CreatePerson = { email: "test@email.be", - firstname: "first_name", - lastname: "last_name", + name: "name", }; const person5: CreatePerson = { github: "testhub.com", - firstname: "person5", - lastname: "second name", + name: "person5", }; +import "../integration_setup"; + it("should create 1 new person where github is null", async () => { const person0: CreatePerson = { email: "test@email.be", - firstname: "first_name", - lastname: "last_name", + name: "name", }; const created_person = await createPerson(person0); expect(created_person).toHaveProperty("github", null); - expect(created_person).toHaveProperty("firstname", person0.firstname); - expect(created_person).toHaveProperty("lastname", person0.lastname); + expect(created_person).toHaveProperty("name", person0.name); expect(created_person).toHaveProperty("email", person0.email); }); it("should create 1 new person where email is null", async () => { const person1: CreatePerson = { github: "testhub.com", - firstname: "person5", - lastname: "second name", + name: "person5", }; const created_person = await createPerson(person1); expect(created_person).toHaveProperty("github", person1.github); - expect(created_person).toHaveProperty("firstname", person1.firstname); - expect(created_person).toHaveProperty("lastname", person1.lastname); + expect(created_person).toHaveProperty("name", person1.name); expect(created_person).toHaveProperty("email", null); }); it("should find all the persons in the db, 2 in total", async () => { const searched_persons = await getAllPersons(); expect(searched_persons[5]).toHaveProperty("github", null); - expect(searched_persons[5]).toHaveProperty("firstname", person4.firstname); - expect(searched_persons[5]).toHaveProperty("lastname", person4.lastname); + expect(searched_persons[5]).toHaveProperty("name", person4.name); expect(searched_persons[5]).toHaveProperty("email", person4.email); expect(searched_persons[6]).toHaveProperty("github", person5.github); - expect(searched_persons[6]).toHaveProperty("firstname", person5.firstname); - expect(searched_persons[6]).toHaveProperty("lastname", person5.lastname); + expect(searched_persons[6]).toHaveProperty("name", person5.name); expect(searched_persons[6]).toHaveProperty("email", null); }); @@ -71,33 +65,17 @@ it("should find all the persons in the db, 2 in total", async () => { });*/ it("should find person 1 in the db, by searching for its firstname", async () => { - const searched_person = await searchPersonByName(person4.firstname); + const searched_person = await searchPersonByName(person4.name); expect(searched_person[0]).toHaveProperty("github", null); - expect(searched_person[0]).toHaveProperty("firstname", person4.firstname); - expect(searched_person[0]).toHaveProperty("lastname", person4.lastname); + expect(searched_person[0]).toHaveProperty("name", person4.name); expect(searched_person[0]).toHaveProperty("email", person4.email); }); -it("should find person 2 in the db, by searching for its lastname", async () => { - const searched_person4 = await searchPersonByName(person5.lastname); - expect(searched_person4[0]).toHaveProperty("github", person5.github); - expect(searched_person4[0]).toHaveProperty("firstname", person5.firstname); - expect(searched_person4[0]).toHaveProperty("lastname", person5.lastname); - expect(searched_person4[0]).toHaveProperty("email", null); -}); - it("should find all the persons in the db with given email, 1 in total", async () => { if (person4.email != undefined) { const searched_persons = await searchPersonByLogin(person4.email); expect(searched_persons[0]).toHaveProperty("github", null); - expect(searched_persons[0]).toHaveProperty( - "firstname", - person4.firstname - ); - expect(searched_persons[0]).toHaveProperty( - "lastname", - person4.lastname - ); + expect(searched_persons[0]).toHaveProperty("name", person4.name); expect(searched_persons[0]).toHaveProperty("email", person4.email); } }); @@ -106,35 +84,26 @@ it("should find all the persons in the db with given github, 1 in total", async if (person5.github) { const searched_persons = await searchPersonByLogin(person5.github); expect(searched_persons[0]).toHaveProperty("github", person5.github); - expect(searched_persons[0]).toHaveProperty( - "firstname", - person5.firstname - ); - expect(searched_persons[0]).toHaveProperty( - "lastname", - person5.lastname - ); + expect(searched_persons[0]).toHaveProperty("name", person5.name); expect(searched_persons[0]).toHaveProperty("email", null); } }); it("should update person based upon personid", async () => { - const searched_person3 = await searchPersonByName(person4.firstname); + const searched_person3 = await searchPersonByName(person4.name); const personUpdate: UpdatePerson = { personId: searched_person3[0].person_id, email: "new@email.be", - firstname: "new_name", - lastname: "different_name", + name: "new_name", }; const updated_person = await updatePerson(personUpdate); expect(updated_person).toHaveProperty("github", null); - expect(updated_person).toHaveProperty("firstname", personUpdate.firstname); - expect(updated_person).toHaveProperty("lastname", personUpdate.lastname); - expect(updated_person).toHaveProperty("email", personUpdate.email); + expect(updated_person).toHaveProperty("name", personUpdate.name); + -expect(updated_person).toHaveProperty("email", personUpdate.email); }); it("should delete the person based upon personid", async () => { - const searched_person5 = await searchPersonByName(person5.lastname); + const searched_person5 = await searchPersonByName(person5.name); const deleted_person = await deletePersonById( searched_person5[0].person_id ); @@ -143,10 +112,6 @@ it("should delete the person based upon personid", async () => { searched_person5[0].person_id ); expect(deleted_person).toHaveProperty("github", deleted_person.github); - expect(deleted_person).toHaveProperty( - "firstname", - deleted_person.firstname - ); - expect(deleted_person).toHaveProperty("lastname", deleted_person.lastname); + expect(deleted_person).toHaveProperty("name", deleted_person.name); expect(deleted_person).toHaveProperty("email", deleted_person.email); }); diff --git a/backend/tests/orm_integration/project.test.ts b/backend/tests/orm_integration/project.test.ts index f29d8fbb..416b78d3 100644 --- a/backend/tests/orm_integration/project.test.ts +++ b/backend/tests/orm_integration/project.test.ts @@ -1,4 +1,8 @@ -import { CreateProject, UpdateProject } from "../../orm_functions/orm_types"; +import { + CreateProject, + FilterProjects, + UpdateProject, +} from "../../orm_functions/orm_types"; import { getOsocByYear } from "../../orm_functions/osoc"; import { createProject, @@ -11,13 +15,11 @@ import { getProjectsStartedBeforeDate, getProjectsStartedAfterDate, getProjectsEndedBeforeDate, - getProjectsByNumberPositions, updateProject, deleteProject, deleteProjectByOsocEdition, deleteProjectByPartner, - getProjectsLessPositions, - getProjectsMorePositions, + filterProjects, } from "../../orm_functions/project"; const project1: CreateProject = { @@ -26,7 +28,7 @@ const project1: CreateProject = { partner: "test-partner", startDate: new Date("2022-07-13"), endDate: new Date("2022-07-15"), - positions: 7, + description: "test-description", }; const project2: UpdateProject = { @@ -36,9 +38,55 @@ const project2: UpdateProject = { partner: "different-partner", startDate: new Date("2022-08-13"), endDate: new Date("2022-08-15"), +}; + +const filteredProject1: FilterProjects = { + project_id: 1, + name: "project 1", + osoc_id: 1, + partner: "partner 1", + start_date: new Date("2022-08-13"), + end_date: new Date("2022-08-15"), positions: 8, + description: "description 1", + project_role: [ + { + positions: 3, + role: { + name: "Front-end developer", + }, + _count: { + contract: 3, + }, + }, + { + positions: 5, + role: { + name: "Back-end developer", + }, + _count: { + contract: 3, + }, + }, + ], + project_user: [ + { + login_user: { + login_user_id: 1, + is_coach: true, + }, + }, + { + login_user: { + login_user_id: 2, + is_coach: true, + }, + }, + ], }; +import "../integration_setup"; + it("should create 1 new project where osoc is 2022", async () => { const osoc = await getOsocByYear(2022); if (osoc) { @@ -49,7 +97,7 @@ it("should create 1 new project where osoc is 2022", async () => { partner: "test-partner", startDate: new Date("2022-07-13"), endDate: new Date("2022-07-15"), - positions: 7, + description: "test-description", }; const created_project = await createProject(project0); @@ -61,7 +109,6 @@ it("should create 1 new project where osoc is 2022", async () => { project0.startDate ); expect(created_project).toHaveProperty("end_date", project0.endDate); - expect(created_project).toHaveProperty("positions", project0.positions); } }); @@ -76,10 +123,6 @@ it("should find all the projects in the db, 3 in total", async () => { project1.startDate ); expect(searched_projects[3]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[3]).toHaveProperty( - "positions", - project1.positions - ); }); it("should return the project, by searching for its name", async () => { @@ -92,7 +135,6 @@ it("should return the project, by searching for its name", async () => { project1.startDate ); expect(searched_project[0]).toHaveProperty("end_date", project1.endDate); - expect(searched_project[0]).toHaveProperty("positions", project1.positions); }); it("should return the project, by searching for its osoc edition", async () => { @@ -110,10 +152,6 @@ it("should return the project, by searching for its osoc edition", async () => { "end_date", project1.endDate ); - expect(searched_project[1]).toHaveProperty( - "positions", - project1.positions - ); } }); @@ -127,10 +165,6 @@ it("should return the projects, by searching for its partner name", async () => project1.startDate ); expect(searched_projects[0]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[0]).toHaveProperty( - "positions", - project1.positions - ); }); it("should return the projects, by searching for its start date", async () => { @@ -143,10 +177,6 @@ it("should return the projects, by searching for its start date", async () => { project1.startDate ); expect(searched_projects[0]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[0]).toHaveProperty( - "positions", - project1.positions - ); }); it("should return the projects, by searching for its end date", async () => { @@ -159,10 +189,6 @@ it("should return the projects, by searching for its end date", async () => { project1.startDate ); expect(searched_projects[0]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[0]).toHaveProperty( - "positions", - project1.positions - ); }); it("should return the projects, by searching for all projects starting before date", async () => { @@ -177,10 +203,6 @@ it("should return the projects, by searching for all projects starting before da project1.startDate ); expect(searched_projects[1]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[1]).toHaveProperty( - "positions", - project1.positions - ); }); it("should return the projects, by searching for all projects starting after date", async () => { @@ -195,10 +217,6 @@ it("should return the projects, by searching for all projects starting after dat project1.startDate ); expect(searched_projects[2]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[2]).toHaveProperty( - "positions", - project1.positions - ); }); it("should return the projects, by searching for all projects ending before date", async () => { @@ -213,10 +231,6 @@ it("should return the projects, by searching for all projects ending before date project1.startDate ); expect(searched_projects[1]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[1]).toHaveProperty( - "positions", - project1.positions - ); }); it("should return the projects, by searching for all projects ending after date", async () => { @@ -231,64 +245,6 @@ it("should return the projects, by searching for all projects ending after date" project1.startDate ); expect(searched_projects[1]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[1]).toHaveProperty( - "positions", - project1.positions - ); -}); - -it("should return the projects, by searching for its number of positions", async () => { - const searched_projects = await getProjectsByNumberPositions( - project1.positions - ); - expect(searched_projects[0]).toHaveProperty("name", project1.name); - expect(searched_projects[0]).toHaveProperty("osoc_id", project1.osocId); - expect(searched_projects[0]).toHaveProperty("partner", project1.partner); - expect(searched_projects[0]).toHaveProperty( - "start_date", - project1.startDate - ); - expect(searched_projects[0]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[0]).toHaveProperty( - "positions", - project1.positions - ); -}); - -it("should return the projects, by searching for all projects with less positions", async () => { - const searched_projects = await getProjectsLessPositions( - project1.positions + 1 - ); - expect(searched_projects[0]).toHaveProperty("name", project1.name); - expect(searched_projects[0]).toHaveProperty("osoc_id", project1.osocId); - expect(searched_projects[0]).toHaveProperty("partner", project1.partner); - expect(searched_projects[0]).toHaveProperty( - "start_date", - project1.startDate - ); - expect(searched_projects[0]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[0]).toHaveProperty( - "positions", - project1.positions - ); -}); - -it("should return the projects, by searching for all projects with more positions", async () => { - const searched_projects = await getProjectsMorePositions( - project1.positions - 1 - ); - expect(searched_projects[3]).toHaveProperty("name", project1.name); - expect(searched_projects[3]).toHaveProperty("osoc_id", project1.osocId); - expect(searched_projects[3]).toHaveProperty("partner", project1.partner); - expect(searched_projects[3]).toHaveProperty( - "start_date", - project1.startDate - ); - expect(searched_projects[3]).toHaveProperty("end_date", project1.endDate); - expect(searched_projects[3]).toHaveProperty( - "positions", - project1.positions - ); }); it("should update project based upon project id", async () => { @@ -301,7 +257,6 @@ it("should update project based upon project id", async () => { expect(updated_project).toHaveProperty("partner", project2.partner); expect(updated_project).toHaveProperty("start_date", project2.startDate); expect(updated_project).toHaveProperty("end_date", project2.endDate); - expect(updated_project).toHaveProperty("positions", project2.positions); }); it("should delete the project based upon project id", async () => { @@ -311,7 +266,6 @@ it("should delete the project based upon project id", async () => { expect(deleted_project).toHaveProperty("partner", project2.partner); expect(deleted_project).toHaveProperty("start_date", project2.startDate); expect(deleted_project).toHaveProperty("end_date", project2.endDate); - expect(deleted_project).toHaveProperty("positions", project2.positions); }); it("should delete the project based upon project partner", async () => { @@ -326,3 +280,49 @@ it("should delete the project based upon osoc id", async () => { expect(deleted_project).toHaveProperty("count", 1); } }); + +it("should return the filtered projects", async () => { + let sumRoles = 0; + for (const role of filteredProject1.project_role) { + sumRoles += role.positions; + } + + const filtered_projects = await filterProjects( + { currentPage: 0, pageSize: 25 }, + filteredProject1.name, + filteredProject1.partner, + filteredProject1.positions === sumRoles, + 2022, + "asc", + "desc", + 1 + ); + + for (const project of filtered_projects.data) { + expect(project).toHaveProperty("name", filteredProject1.name); + expect(project).toHaveProperty("partner", filteredProject1.partner); + expect(project).toHaveProperty("positions", filteredProject1.positions); + expect(project).toHaveProperty( + "description", + filteredProject1.description + ); + expect(project).toHaveProperty( + "project_id", + filteredProject1.project_id + ); + expect(project).toHaveProperty("osoc_id", filteredProject1.osoc_id); + expect(project).toHaveProperty( + "project_role", + filteredProject1.project_role + ); + expect(project).toHaveProperty("end_date", filteredProject1.end_date); + expect(project).toHaveProperty( + "start_date", + filteredProject1.start_date + ); + expect(project).toHaveProperty( + "project_user", + filteredProject1.project_user + ); + } +}); diff --git a/backend/tests/orm_integration/project_role.test.ts b/backend/tests/orm_integration/project_role.test.ts index 9870beb4..0221719e 100644 --- a/backend/tests/orm_integration/project_role.test.ts +++ b/backend/tests/orm_integration/project_role.test.ts @@ -28,6 +28,8 @@ const projectRole2: UpdateProjectRole = { positions: 3, }; +import "../integration_setup"; + it("should create 1 new project role with role developer", async () => { const projects = await getAllProjects(); const role = await getRolesByName("Developer"); diff --git a/backend/tests/orm_integration/role.test.ts b/backend/tests/orm_integration/role.test.ts index c82650f7..9188f24c 100644 --- a/backend/tests/orm_integration/role.test.ts +++ b/backend/tests/orm_integration/role.test.ts @@ -21,6 +21,8 @@ const role2: UpdateRole = { name: "Web Designer", }; +import "../integration_setup"; + it("should create 1 new role where", async () => { const created__role = await createRole("Data Scientist"); role1.roleId = created__role.role_id; diff --git a/backend/tests/orm_integration/session_key.test.ts b/backend/tests/orm_integration/session_key.test.ts index fed256cc..f2fd0ae9 100644 --- a/backend/tests/orm_integration/session_key.test.ts +++ b/backend/tests/orm_integration/session_key.test.ts @@ -6,6 +6,8 @@ import { removeAllKeysForUser, } from "../../orm_functions/session_key"; +import "../integration_setup"; + it("should create a new session key for the given login user", async () => { const loginUsers = await prisma.login_user.findMany(); diff --git a/backend/tests/orm_integration/student.test.ts b/backend/tests/orm_integration/student.test.ts index d0f9b2ed..ad4be09e 100644 --- a/backend/tests/orm_integration/student.test.ts +++ b/backend/tests/orm_integration/student.test.ts @@ -27,6 +27,8 @@ const student2: UpdateStudent = { alumni: true, }; +import "../integration_setup"; + it("should create 1 new student", async () => { const person = await prisma.person.findMany(); if (person) { diff --git a/backend/tests/orm_unit/evaluation.test.ts b/backend/tests/orm_unit/evaluation.test.ts index 3aef60d2..43853b6d 100644 --- a/backend/tests/orm_unit/evaluation.test.ts +++ b/backend/tests/orm_unit/evaluation.test.ts @@ -3,6 +3,8 @@ import { decision_enum } from "@prisma/client"; import { checkIfFinalEvaluationExists, createEvaluationForStudent, + deleteEvaluationsByJobApplication, + getEvaluationByPartiesFor, getLoginUserByEvaluationId, updateEvaluationForStudent, } from "../../orm_functions/evaluation"; @@ -122,3 +124,40 @@ test("should return the loginUser with his info that made this evaluation", asyn prismaMock.evaluation.findUnique.mockResolvedValue(result); await expect(getLoginUserByEvaluationId(7)).resolves.toEqual(result); }); + +test("should return all evaluations created by a user for a student in an osoc edition", async () => { + const evaluations = [ + { + evaluation_id: 1, + login_user_id: 1, + decision: decision_enum.YES, + motivation: "Definitely unicorn, all in for it", + is_final: true, + job_application_id: 1, + }, + { + evaluation_id: 2, + login_user_id: 1, + decision: decision_enum.MAYBE, + motivation: "Definitely unicorn, all in for it", + is_final: false, + job_application_id: 1, + }, + ]; + + prismaMock.evaluation.findMany.mockResolvedValue(evaluations); + + await expect(getEvaluationByPartiesFor(1, 1, 1)).resolves.toEqual( + evaluations + ); +}); + +it("should delete evaluations by a job application", async () => { + const numberOfDeletions = { count: 5 }; + + prismaMock.evaluation.deleteMany.mockResolvedValue(numberOfDeletions); + + await expect(deleteEvaluationsByJobApplication(1)).resolves.toEqual( + numberOfDeletions + ); +}); diff --git a/backend/tests/orm_unit/job_application.test.ts b/backend/tests/orm_unit/job_application.test.ts index 8c5b6c25..4f4c20e4 100644 --- a/backend/tests/orm_unit/job_application.test.ts +++ b/backend/tests/orm_unit/job_application.test.ts @@ -6,6 +6,7 @@ import { deleteJobApplicationsFromStudent, getJobApplication, getJobApplicationByYear, + getJobApplicationByYearForStudent, getLatestApplicationRolesForStudent, getLatestJobApplicationOfStudent, getStudentEvaluationsFinal, @@ -31,7 +32,7 @@ const response = { edu_duration: 5, edu_year: "2025", edu_institute: "ugent", - email_status: email_status_enum.FAILED, + email_status: email_status_enum.REJECTED, created_at: new Date(), }; @@ -60,7 +61,7 @@ test("should delete job applications of student", async () => { test("should change the email status", async () => { prismaMock.job_application.update.mockResolvedValue(response); await expect( - changeEmailStatusOfJobApplication(0, email_status_enum.FAILED) + changeEmailStatusOfJobApplication(0, email_status_enum.REJECTED) ).resolves.toEqual(response); }); @@ -77,7 +78,7 @@ test("should create a job application", async () => { eduLevel: "good", eduYear: "2025", edus: ["good"], - emailStatus: email_status_enum.DRAFT, + emailStatus: email_status_enum.APPLIED, funFact: "cool", studentVolunteerInfo: "Yes, I can work with a student employment agreement in Belgium", @@ -116,3 +117,10 @@ test("should return the latest roles this student has applied for", async () => response ); }); + +test("should return the job application of a student (for a certain year)", async () => { + prismaMock.job_application.findMany.mockResolvedValue([response]); + await expect(getJobApplicationByYearForStudent(0, 2022)).resolves.toEqual( + response + ); +}); diff --git a/backend/tests/orm_unit/login_user.test.ts b/backend/tests/orm_unit/login_user.test.ts index 82f790e8..8761a1d8 100644 --- a/backend/tests/orm_unit/login_user.test.ts +++ b/backend/tests/orm_unit/login_user.test.ts @@ -20,8 +20,15 @@ import { setCoach, setAdmin, filterLoginUsers, + deleteLoginUserFromDB, + getOsocYearsForLoginUser, } from "../../orm_functions/login_user"; +// mock that is used to mock the deletePersonFromDB function +import * as personORM from "../../orm_functions/person"; +jest.mock("../../orm_functions/person"); +export const personORMMock = personORM as jest.Mocked; + const response = { session_id: "50", login_user_id: 1, @@ -31,6 +38,13 @@ const response = { is_coach: false, session_keys: ["key1", "key2"], account_status: account_status_enum.DISABLED, + login_user_osoc: [ + { + osoc: { + year: 2022, + }, + }, + ], }; const returnValue = { @@ -120,6 +134,14 @@ test("should delete the login user with the given person id and return the delet await expect(deleteLoginUserByPersonId(0)).resolves.toEqual(returnValue); }); +test("should delete all data of a login_user", async () => { + personORMMock.deletePersonFromDB.mockResolvedValue(); + prismaMock.login_user.findUnique.mockResolvedValue(response); + + await deleteLoginUserFromDB(0); + expect(personORMMock.deletePersonFromDB).toBeCalledTimes(1); +}); + test("should return the login_user with given id", async () => { prismaMock.login_user.findUnique.mockResolvedValue(response); await expect(getLoginUserById(0)).resolves.toEqual(response); @@ -129,6 +151,7 @@ test("should return the filtered list of users", async () => { prismaMock.login_user.findMany.mockResolvedValue([returnValue]); await expect( filterLoginUsers( + { currentPage: 0, pageSize: 25 }, undefined, undefined, undefined, @@ -137,12 +160,16 @@ test("should return the filtered list of users", async () => { undefined, undefined ) - ).resolves.toEqual([returnValue]); + ).resolves.toEqual({ + data: [returnValue], + pagination: { count: undefined, page: 0 }, + }); }); test("should reject and throw an error because only sorting on 1 field is allowed", async () => { try { await filterLoginUsers( + { currentPage: 0, pageSize: 25 }, undefined, undefined, "asc", @@ -168,3 +195,8 @@ test("should return the updated login_user", async () => { prismaMock.login_user.update.mockResolvedValue(response); await expect(setAdmin(0, true)).resolves.toEqual(response); }); + +test("should return a list of years that should be visible", async () => { + prismaMock.login_user.findUnique.mockResolvedValue(response); + await expect(getOsocYearsForLoginUser(0)).resolves.toEqual([2022]); +}); diff --git a/backend/tests/orm_unit/login_user_osoc.test.ts b/backend/tests/orm_unit/login_user_osoc.test.ts new file mode 100644 index 00000000..9519503c --- /dev/null +++ b/backend/tests/orm_unit/login_user_osoc.test.ts @@ -0,0 +1,69 @@ +import { prismaMock } from "./singleton"; +import { + addOsocToUser, + deleteOsocsForLoginuser, + deleteOsocsLoginConnectionFromOsoc, + getLoginUserOsocByIds, + getOsocYearsForLoginUserById, + removeOsocFromUser, +} from "../../orm_functions/login_user_osoc"; + +const entries = [ + { + login_user_id: 0, + login_user_osoc_id: 0, + osoc_id: 0, + }, +]; + +test("should return the entry with given id's", async () => { + prismaMock.login_user_osoc.findMany.mockResolvedValue(entries); + + await expect(getLoginUserOsocByIds(0, 0)).resolves.toEqual(entries[0]); +}); + +test("should return null because the entry does not exist", async () => { + prismaMock.login_user_osoc.findMany.mockResolvedValue([]); + await expect(getLoginUserOsocByIds(0, 0)).resolves.toEqual(null); +}); + +test("should connect a login user with an osoc edition", async () => { + prismaMock.login_user_osoc.findMany.mockResolvedValue([]); + + const expected = { + login_user_osoc_id: 0, + login_user_id: 0, + osoc_id: 0, + }; + + prismaMock.login_user_osoc.create.mockResolvedValue(expected); + await expect(addOsocToUser(0, 0)).resolves.toEqual(expected); +}); + +test("should delete the instances related to the userId", async () => { + const expected = { count: 0 }; + prismaMock.login_user_osoc.deleteMany.mockResolvedValue(expected); + await expect(deleteOsocsForLoginuser(0)).resolves.toEqual(expected); +}); + +test("should delete the instances related to the osocId", async () => { + const expected = { count: 0 }; + prismaMock.login_user_osoc.deleteMany.mockResolvedValue(expected); + await expect(deleteOsocsLoginConnectionFromOsoc(0)).resolves.toEqual( + expected + ); +}); + +test("should connect a login user with an osoc edition", async () => { + prismaMock.login_user_osoc.findMany.mockResolvedValue(entries); + + const expected = { count: 0 }; + + prismaMock.login_user_osoc.deleteMany.mockResolvedValue(expected); + await expect(removeOsocFromUser(0, 0)).resolves.toEqual(expected); +}); + +test("should return a list of visible editions", async () => { + prismaMock.login_user_osoc.findMany.mockResolvedValue(entries); + await expect(getOsocYearsForLoginUserById(0)).resolves.toEqual(entries); +}); diff --git a/backend/tests/orm_unit/osoc.test.ts b/backend/tests/orm_unit/osoc.test.ts index 152580c2..c70ca39a 100644 --- a/backend/tests/orm_unit/osoc.test.ts +++ b/backend/tests/orm_unit/osoc.test.ts @@ -9,8 +9,13 @@ import { getOsocByYear, updateOsoc, getLatestOsoc, + deleteOsocFromDB, + getNewestOsoc, + filterOsocs, + getOsocById, } from "../../orm_functions/osoc"; import { UpdateOsoc } from "../../orm_functions/orm_types"; +import { account_status_enum, email_status_enum } from "@prisma/client"; const returnValue = { osoc_id: 0, @@ -92,3 +97,240 @@ test("should delete the given osoc by year and return the deleted record", async prismaMock.osoc.delete.mockResolvedValue(returnValue); await expect(deleteOsocByYear(2022)).resolves.toEqual(returnValue); }); + +test("should delete everything associated with the give osoc edition", async () => { + prismaMock.project.findMany.mockResolvedValue([ + { + project_id: 0, + name: "", + osoc_id: 0, + partner: "", + description: "", + start_date: new Date(), + end_date: new Date(), + }, + ]); + prismaMock.project_role.findMany.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 0, + }, + ]); + prismaMock.job_application.findMany.mockResolvedValue([ + { + job_application_id: 0, + student_id: 0, + student_volunteer_info: "", + responsibilities: "", + fun_fact: "", + student_coach: false, + osoc_id: 0, + edus: [""], + edu_level: "", + edu_duration: 0, + edu_year: "", + edu_institute: "", + email_status: email_status_enum.APPLIED, + created_at: new Date(), + }, + ]); + prismaMock.project_user.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.login_user_osoc.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.contract.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.project_role.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.project.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.evaluation.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.applied_role.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.job_application_skill.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.attachment.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.job_application.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.osoc.delete.mockResolvedValue({ + osoc_id: 0, + year: 0, + }); + + await deleteOsocFromDB(0); + + expect(prismaMock.project.findMany).toBeCalledTimes(1); + expect(prismaMock.project_role.findMany).toBeCalledTimes(1); + expect(prismaMock.job_application.findMany).toBeCalledTimes(1); + expect(prismaMock.project_user.deleteMany).toBeCalledTimes(1); + expect(prismaMock.login_user_osoc.deleteMany).toBeCalledTimes(1); + expect(prismaMock.contract.deleteMany).toBeCalledTimes(1); + expect(prismaMock.project_role.deleteMany).toBeCalledTimes(1); + expect(prismaMock.project.deleteMany).toBeCalledTimes(1); + expect(prismaMock.evaluation.deleteMany).toBeCalledTimes(1); + expect(prismaMock.applied_role.deleteMany).toBeCalledTimes(1); + expect(prismaMock.job_application_skill.deleteMany).toBeCalledTimes(1); + expect(prismaMock.attachment.deleteMany).toBeCalledTimes(1); + expect(prismaMock.job_application.deleteMany).toBeCalledTimes(1); + expect(prismaMock.osoc.delete).toBeCalledTimes(1); +}); + +test("should return the newest osoc edition", async () => { + const expected = { + osoc_id: 0, + year: 2022, + }; + + prismaMock.osoc.findFirst.mockResolvedValue(expected); + const res = await getNewestOsoc(); + expect(res).toHaveProperty("osoc_id"); + expect(res).toHaveProperty("year"); + expect(prismaMock.osoc.findFirst).toBeCalledTimes(1); +}); + +test("should return filtered list of osocs", async () => { + const expected = [ + { + osoc_id: 0, + year: 2022, + }, + ]; + + const user_response = { + session_id: "50", + login_user_id: 1, + person_id: 0, + password: "password", + is_admin: false, + is_coach: false, + session_keys: ["key1", "key2"], + account_status: account_status_enum.DISABLED, + login_user_osoc: [ + { + osoc: { + year: 2022, + }, + }, + ], + }; + prismaMock.login_user.findUnique.mockResolvedValue(user_response); + prismaMock.osoc.findMany.mockResolvedValue(expected); + const res = await filterOsocs( + { currentPage: 0, pageSize: 25 }, + 2022, + undefined, + 0 + ); + res.data.forEach((val) => { + expect(val).toHaveProperty("osoc_id"); + expect(val).toHaveProperty("year"); + }); + expect(prismaMock.osoc.findMany).toBeCalledTimes(1); +}); + +test("should return filtered list of osocs", async () => { + const expected = [ + { + osoc_id: 0, + year: 2022, + }, + ]; + + const user_response = { + session_id: "50", + login_user_id: 1, + person_id: 0, + password: "password", + is_admin: false, + is_coach: false, + session_keys: ["key1", "key2"], + account_status: account_status_enum.DISABLED, + login_user_osoc: [ + { + osoc: { + year: 2022, + }, + }, + ], + }; + prismaMock.login_user.findUnique.mockResolvedValue(user_response); + prismaMock.osoc.findMany.mockResolvedValue(expected); + const res = await filterOsocs( + { currentPage: 0, pageSize: 25 }, + 2022, + undefined, + 0 + ); + expect(res.pagination).toStrictEqual({ page: 0, count: undefined }); + res.data.forEach((val) => { + expect(val).toHaveProperty("osoc_id"); + expect(val).toHaveProperty("year"); + }); + expect(prismaMock.osoc.findMany).toBeCalledTimes(1); +}); + +test("should return filtered list of osocs", async () => { + const expected = [ + { + osoc_id: 0, + year: 2022, + }, + ]; + + const user_response = { + session_id: "50", + login_user_id: 1, + person_id: 0, + password: "password", + is_admin: false, + is_coach: false, + session_keys: ["key1", "key2"], + account_status: account_status_enum.DISABLED, + login_user_osoc: [ + { + osoc: { + year: 0, + }, + }, + ], + }; + prismaMock.login_user.findUnique.mockResolvedValue(user_response); + prismaMock.osoc.findMany.mockResolvedValue(expected); + const res = await filterOsocs( + { currentPage: 0, pageSize: 25 }, + 2022, + undefined, + 0 + ); + res.data.forEach((val) => { + expect(val).toHaveProperty("osoc_id"); + expect(val).toHaveProperty("year"); + }); + expect(prismaMock.osoc.findMany).toBeCalledTimes(0); +}); + +test("should return the found osoc edition", async () => { + const osoc = { + osoc_id: 0, + year: 0, + }; + prismaMock.osoc.findUnique.mockResolvedValue(osoc); + await expect(getOsocById(0)).resolves.toEqual(osoc); +}); + +test("should return filtered list of osocs (yearFilter is undefined)", async () => { + const expected = [ + { + osoc_id: 0, + year: 2022, + }, + ]; + + prismaMock.osoc.findMany.mockResolvedValue(expected); + const res = await filterOsocs( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + 0 + ); + expect(res.pagination).toStrictEqual({ page: 0, count: undefined }); + res.data.forEach((val) => { + expect(val).toHaveProperty("osoc_id"); + expect(val).toHaveProperty("year"); + }); + expect(prismaMock.osoc.findMany).toBeCalledTimes(1); +}); diff --git a/backend/tests/orm_unit/person.test.ts b/backend/tests/orm_unit/person.test.ts index 66216707..87196155 100644 --- a/backend/tests/orm_unit/person.test.ts +++ b/backend/tests/orm_unit/person.test.ts @@ -3,18 +3,20 @@ import { CreatePerson, UpdatePerson } from "../../orm_functions/orm_types"; import { createPerson, deletePersonById, + deletePersonFromDB, getAllPersons, getPasswordPersonByEmail, + getPasswordPersonByGithub, searchPersonByLogin, searchPersonByName, updatePerson, } from "../../orm_functions/person"; +import { account_status_enum, email_status_enum } from "@prisma/client"; const returnValue = { person_id: 0, email: "email@mail.com", - firstname: "FirstName", - lastname: "LastName", + name: "name", github: null, github_id: "666", }; @@ -22,8 +24,7 @@ const returnValue = { test("should create a person in the db with the given object, returns the new record", async () => { const person: CreatePerson = { email: "email@mail.com", - firstname: "FirstName", - lastname: "LastName", + name: "name", }; prismaMock.person.create.mockResolvedValue(returnValue); @@ -42,6 +43,13 @@ test("should return the HASHED password of the given email", async () => { ); }); +test("should return the password of the user with given github", async () => { + prismaMock.person.findUnique.mockResolvedValue(returnValue); + await expect(getPasswordPersonByGithub("github name")).resolves.toEqual( + returnValue + ); +}); + test("should return the searched person record with the given name", async () => { prismaMock.person.findMany.mockResolvedValue([returnValue]); await expect(searchPersonByName("name")).resolves.toEqual([returnValue]); @@ -57,9 +65,8 @@ test("should return all the people with the given login (email or github)", asyn test("should update the person with the new data and return the updated record", async () => { const person: UpdatePerson = { email: "email@mail.com", - firstname: "newFirst", + name: "new_name", github: null, - lastname: "", personId: 0, }; @@ -71,3 +78,79 @@ test("should delete the person with the given id and return the deleted record", prismaMock.person.delete.mockResolvedValue(returnValue); await expect(deletePersonById(0)).resolves.toEqual(returnValue); }); + +test("should delete a person with the given id from the database", async () => { + const person = { + person_id: 0, + email: "", + github: "", + name: "", + github_id: "", + login_user: { + login_user_id: 0, + }, + student: { + student_id: 0, + }, + }; + + prismaMock.person.findUnique.mockResolvedValue(person); + prismaMock.password_reset.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.project_user.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.session_keys.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.login_user.delete.mockResolvedValue({ + login_user_id: 0, + person_id: 0, + password: "", + is_admin: false, + is_coach: true, + account_status: account_status_enum.DISABLED, + }); + prismaMock.job_application.findMany.mockResolvedValue([ + { + job_application_id: 0, + student_id: 0, + student_volunteer_info: "", + responsibilities: "", + fun_fact: "", + student_coach: false, + osoc_id: 0, + edus: [""], + edu_level: "", + edu_duration: 0, + edu_year: "", + edu_institute: "", + email_status: email_status_enum.APPLIED, + created_at: new Date(), + }, + ]); + prismaMock.attachment.deleteMany.mockResolvedValue({ count: 0 }); + prismaMock.student.delete.mockResolvedValue({ + student_id: 0, + person_id: 0, + gender: "", + pronouns: "", + phone_number: "", + nickname: "", + alumni: false, + }); + prismaMock.person.delete.mockResolvedValue({ + person_id: 0, + email: "", + github: "", + name: "", + github_id: "", + }); + + await deletePersonFromDB(0); + + expect(prismaMock.person.findUnique).toBeCalledTimes(1); + expect(prismaMock.password_reset.deleteMany).toBeCalledTimes(1); + expect(prismaMock.project_user.deleteMany).toBeCalledTimes(1); + expect(prismaMock.session_keys.deleteMany).toBeCalledTimes(1); + expect(prismaMock.login_user.delete).toBeCalledTimes(1); + expect(prismaMock.job_application.findMany).toBeCalledTimes(1); + expect(prismaMock.attachment.deleteMany).toBeCalledTimes(1); + expect(prismaMock.student.delete).toBeCalledTimes(1); + expect(prismaMock.person.delete).toBeCalledTimes(1); +}); diff --git a/backend/tests/orm_unit/project.test.ts b/backend/tests/orm_unit/project.test.ts index d6725b7e..d48be471 100644 --- a/backend/tests/orm_unit/project.test.ts +++ b/backend/tests/orm_unit/project.test.ts @@ -1,5 +1,9 @@ import { prismaMock } from "./singleton"; -import { CreateProject, UpdateProject } from "../../orm_functions/orm_types"; +import { + FilterProjects, + UpdateProject, + CreateProject, +} from "../../orm_functions/orm_types"; import { createProject, getProjectByName, @@ -12,15 +16,35 @@ import { getProjectsByEndDate, getProjectsEndedBeforeDate, getProjectsEndedAfterDate, - getProjectsByNumberPositions, - getProjectsLessPositions, - getProjectsMorePositions, deleteProject, updateProject, deleteProjectByOsocEdition, + deleteProjectFromDB, deleteProjectByPartner, getProjectById, + filterProjects, + getProjectYear, } from "../../orm_functions/project"; +import { account_status_enum } from "@prisma/client"; +import { errors } from "../../utility"; + +const user_return = { + session_id: "50", + login_user_id: 1, + person_id: 0, + password: "password", + is_admin: false, + is_coach: false, + session_keys: ["key1", "key2"], + account_status: account_status_enum.DISABLED, + login_user_osoc: [ + { + osoc: { + year: 2022, + }, + }, + ], +}; const returnValue = { project_id: 0, @@ -33,6 +57,87 @@ const returnValue = { description: "", }; +const filteredProject1: FilterProjects = { + project_id: 1, + name: "project 1", + osoc_id: 1, + partner: "partner 1", + start_date: new Date("2022-08-13"), + end_date: new Date("2022-08-15"), + positions: 8, + description: "description 1", + project_role: [ + { + positions: 3, + role: { + name: "Front-end developer", + }, + _count: { + contract: 3, + }, + }, + { + positions: 5, + role: { + name: "Back-end developer", + }, + _count: { + contract: 5, + }, + }, + ], + project_user: [ + { + login_user: { + login_user_id: 1, + is_coach: true, + }, + }, + { + login_user: { + login_user_id: 2, + is_coach: true, + }, + }, + ], +}; + +const filteredProject2: FilterProjects = { + project_id: 1, + name: "project 1", + osoc_id: 1, + partner: "partner 1", + start_date: new Date("2022-08-13"), + end_date: new Date("2022-08-15"), + positions: 1, + description: "description 1", + project_role: [ + { + positions: 1, + role: { + name: "Front-end developer", + }, + _count: { + contract: 0, + }, + }, + ], + project_user: [ + { + login_user: { + login_user_id: 1, + is_coach: true, + }, + }, + { + login_user: { + login_user_id: 2, + is_coach: true, + }, + }, + ], +}; + test("should create a project in the db with the given object, returns the new record", async () => { const project: CreateProject = { name: "Test project", @@ -40,7 +145,7 @@ test("should create a project in the db with the given object, returns the new r partner: "Best partner", startDate: new Date("2022-07-13"), endDate: new Date("2022-08-31"), - positions: 10, + description: "Description of the project", }; prismaMock.project.create.mockResolvedValue(returnValue); @@ -118,23 +223,6 @@ test("should return all the project that ended before the given end date", async ).resolves.toEqual([returnValue]); }); -test("should return all the projects with the given number of positions", async () => { - prismaMock.project.findMany.mockResolvedValue([returnValue]); - await expect(getProjectsByNumberPositions(10)).resolves.toEqual([ - returnValue, - ]); -}); - -test("should return all the projects with less positions", async () => { - prismaMock.project.findMany.mockResolvedValue([returnValue]); - await expect(getProjectsLessPositions(20)).resolves.toEqual([returnValue]); -}); - -test("should return all the projects with more positions", async () => { - prismaMock.project.findMany.mockResolvedValue([returnValue]); - await expect(getProjectsMorePositions(5)).resolves.toEqual([returnValue]); -}); - test("should update the project with the new data and return the updated record", async () => { const project: UpdateProject = { projectId: 0, @@ -143,7 +231,6 @@ test("should update the project with the new data and return the updated record" partner: "UGent", startDate: new Date("2022-06-05"), endDate: new Date("2022-09-16"), - positions: 7, }; prismaMock.project.update.mockResolvedValue(returnValue); @@ -166,3 +253,298 @@ test("should delete all the projects with the given partner name and return the prismaMock.project.deleteMany.mockResolvedValue(count); await expect(deleteProjectByPartner("UGent")).resolves.toEqual(count); }); + +test("should return all filtered projects by name", async () => { + prismaMock.login_user.findUnique.mockResolvedValue(user_return); + prismaMock.project.findMany.mockResolvedValue([filteredProject1]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + "project 1", + undefined, + undefined, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ + data: [filteredProject1], + pagination: { page: 0, count: 1 }, + }); +}); + +test("should return all filtered projects by partner", async () => { + prismaMock.login_user.findUnique.mockResolvedValue(user_return); + prismaMock.project.findMany.mockResolvedValue([filteredProject1]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + "partner 1", + undefined, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ + data: [filteredProject1], + pagination: { page: 0, count: 1 }, + }); +}); + +test("should return all filtered projects by assigned coaches", async () => { + prismaMock.login_user.findUnique.mockResolvedValue(user_return); + prismaMock.project.findMany.mockResolvedValue([filteredProject1]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ + data: [filteredProject1], + pagination: { page: 0, count: 1 }, + }); +}); + +test("should return all filtered projects by fully assigned status", async () => { + prismaMock.login_user.findUnique.mockResolvedValue(user_return); + prismaMock.project.findMany.mockResolvedValue([filteredProject1]); + prismaMock.contract.findMany.mockResolvedValue([ + { + contract_id: 1, + student_id: 1, + project_role_id: 1, + information: "info", + created_by_login_user_id: 1, + contract_status: "APPROVED", + }, + ]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + true, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ + pagination: { count: 1, page: 0 }, + data: [filteredProject1], + }); +}); + +test("should return all filtered projects sorted by the fully assigned status", async () => { + prismaMock.project.findMany.mockResolvedValue([ + filteredProject2, + filteredProject1, + ]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + undefined, + undefined, + undefined, + "desc", + 0 + ) + ).resolves.toEqual({ + data: [filteredProject2, filteredProject1], + pagination: { count: 2, page: 0 }, + }); + + prismaMock.project.findMany.mockResolvedValue([ + filteredProject1, + filteredProject2, + ]); + + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + undefined, + undefined, + undefined, + "desc", + 0 + ) + ).resolves.toEqual({ + data: [filteredProject1, filteredProject2], + pagination: { count: 2, page: 0 }, + }); +}); + +test("should return all filtered projects sorted by the fully assigned status", async () => { + prismaMock.project.findMany.mockResolvedValue([ + filteredProject2, + filteredProject1, + ]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + undefined, + undefined, + undefined, + "desc", + 0 + ) + ).resolves.toEqual({ + data: [filteredProject2, filteredProject1], + pagination: { count: 2, page: 0 }, + }); + + prismaMock.project.findMany.mockResolvedValue([ + filteredProject1, + filteredProject2, + ]); + + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + undefined, + undefined, + "asc", + undefined, + 0 + ) + ).resolves.toEqual({ + data: [filteredProject1, filteredProject2], + pagination: { count: 2, page: 0 }, + }); +}); + +test("should return the year a project belongs to", async () => { + const val = { + project_id: 0, + description: "", + partner: "", + osoc: { + year: 2022, + }, + start_date: new Date(), + end_date: new Date(), + name: "", + positions: 0, + osoc_id: 0, + }; + prismaMock.project.findUnique.mockResolvedValue(val); + await expect(getProjectYear(0)).resolves.toEqual(2022); +}); + +test("should return the year a project belongs to", async () => { + prismaMock.project.findUnique.mockResolvedValue(null); + await expect(getProjectYear(0)).rejects.toBe(errors.cookInvalidID()); +}); + +test("should return all filtered projects by fully assigned status (sortObject = [{ name: projectNameSort }])", async () => { + prismaMock.project.findMany.mockResolvedValue([filteredProject1]); + prismaMock.contract.findMany.mockResolvedValue([ + { + contract_id: 1, + student_id: 1, + project_role_id: 1, + information: "info", + created_by_login_user_id: 1, + contract_status: "APPROVED", + }, + ]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + true, + undefined, + undefined, + "asc", + 0 + ) + ).resolves.toEqual({ + data: [filteredProject1], + pagination: { page: 0, count: 1 }, + }); +}); + +test("should return all filtered projects by fully assigned status (sortObject = [{ partner: clientNameSort }])", async () => { + prismaMock.project.findMany.mockResolvedValue([filteredProject1]); + prismaMock.contract.findMany.mockResolvedValue([ + { + contract_id: 1, + student_id: 1, + project_role_id: 1, + information: "info", + created_by_login_user_id: 1, + contract_status: "APPROVED", + }, + ]); + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + true, + undefined, + "asc", + "desc", + 0 + ) + ).resolves.toEqual({ + data: [filteredProject1], + pagination: { page: 0, count: 1 }, + }); +}); + +test("should return all filtered projects by fully assigned status (sortObject = [{ partner: clientNameSort }])", async () => { + prismaMock.project.findMany.mockResolvedValue([filteredProject2]); + prismaMock.contract.findMany.mockResolvedValue([ + { + contract_id: 1, + student_id: 1, + project_role_id: 1, + information: "info", + created_by_login_user_id: 1, + contract_status: "APPROVED", + }, + ]); + + await expect( + filterProjects( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + true, + undefined, + "asc", + "desc", + 0 + ) + ).resolves.toEqual({ + data: [], + pagination: { page: 0, count: 0 }, + }); +}); + +test("should delete project", async () => { + const count = { count: 1 }; + prismaMock.project_user.deleteMany.mockResolvedValue(count); + prismaMock.project_role.deleteMany.mockResolvedValue(count); + prismaMock.project.delete.mockResolvedValue(returnValue); + await expect(deleteProjectFromDB(0)).resolves.toEqual(undefined); +}); diff --git a/backend/tests/orm_unit/project_role.test.ts b/backend/tests/orm_unit/project_role.test.ts index 11d23627..d6473f74 100644 --- a/backend/tests/orm_unit/project_role.test.ts +++ b/backend/tests/orm_unit/project_role.test.ts @@ -11,6 +11,7 @@ import { getProjectRoleNamesByProject, updateProjectRole, deleteProjectRole, + getProjectRoleById, } from "../../orm_functions/project_role"; const returnValue = { @@ -86,3 +87,15 @@ test("should return null because the project_role with given ID was not found", prismaMock.project_role.findUnique.mockResolvedValue(null); await expect(getNumberOfFreePositions(0)).resolves.toEqual(null); }); + +test("should return the projectrole that belongs to the projectRoleId", async () => { + const res = { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 0, + }; + + prismaMock.project_role.findUnique.mockResolvedValue(res); + await expect(getProjectRoleById(0)).resolves.toEqual(res); +}); diff --git a/backend/tests/orm_unit/project_user.test.ts b/backend/tests/orm_unit/project_user.test.ts index 9e7d5266..c11d3cab 100644 --- a/backend/tests/orm_unit/project_user.test.ts +++ b/backend/tests/orm_unit/project_user.test.ts @@ -1,6 +1,10 @@ import { prismaMock } from "./singleton"; -import { CreateProjectUser } from "../../orm_functions/orm_types"; -import { createProjectUser } from "../../orm_functions/project_user"; +import { ProjectUser } from "../../orm_functions/orm_types"; +import { + createProjectUser, + deleteProjectUser, + getUsersFor, +} from "../../orm_functions/project_user"; const returnValue = { project_user_id: 0, @@ -9,7 +13,7 @@ const returnValue = { }; test("should create an project user in the db with the given object, returns the new record", async () => { - const projectUser: CreateProjectUser = { + const projectUser: ProjectUser = { loginUserId: 0, projectId: 0, }; @@ -17,3 +21,17 @@ test("should create an project user in the db with the given object, returns the prismaMock.project_user.create.mockResolvedValue(returnValue); await expect(createProjectUser(projectUser)).resolves.toEqual(returnValue); }); + +test("should return the login users associated with the project", async () => { + prismaMock.project_user.findMany.mockResolvedValue([returnValue]); + await expect(getUsersFor(0)).resolves.toEqual([returnValue]); +}); + +test("should delete the project user with the given id and return the deleted record", async () => { + const returnCount = { count: 0 }; + + prismaMock.project_user.deleteMany.mockResolvedValue(returnCount); + await expect( + deleteProjectUser({ loginUserId: 0, projectId: 0 }) + ).resolves.toEqual(returnCount); +}); diff --git a/backend/tests/orm_unit/session_key.test.ts b/backend/tests/orm_unit/session_key.test.ts index 8e6c1323..47bb3393 100644 --- a/backend/tests/orm_unit/session_key.test.ts +++ b/backend/tests/orm_unit/session_key.test.ts @@ -4,6 +4,7 @@ import { refreshKey, checkSessionKey, removeAllKeysForUser, + removeAllKeysForLoginUserId, } from "../../orm_functions/session_key"; const futureDate = new Date(); @@ -66,3 +67,9 @@ test("should remove all keys from the user with the given key", async () => { prismaMock.session_keys.deleteMany.mockResolvedValue(count); await expect(removeAllKeysForUser("key")).resolves.toEqual(count); }); + +test("should remove all keys from the login user", async () => { + const res = { count: 0 }; + prismaMock.session_keys.deleteMany.mockResolvedValue(res); + await expect(removeAllKeysForLoginUserId(0)).resolves.toEqual(res); +}); diff --git a/backend/tests/orm_unit/student.test.ts b/backend/tests/orm_unit/student.test.ts index 9832aace..ef5f5706 100644 --- a/backend/tests/orm_unit/student.test.ts +++ b/backend/tests/orm_unit/student.test.ts @@ -3,11 +3,20 @@ import { CreateStudent, UpdateStudent } from "../../orm_functions/orm_types"; import { createStudent, deleteStudent, + deleteStudentFromDB, + filterStudents, getAllStudents, + getAppliedYearsForStudent, getStudent, searchStudentByGender, updateStudent, } from "../../orm_functions/student"; +import { account_status_enum, decision_enum } from "@prisma/client"; + +// mock that is used to mock the deletePersonFromDB function +import * as personORM from "../../orm_functions/person"; +jest.mock("../../orm_functions/person"); +export const personORMMock = personORM as jest.Mocked; const response = { student_id: 0, @@ -61,7 +70,236 @@ test("should delete the student", async () => { await expect(deleteStudent(0)).resolves.toEqual(response); }); +test("should delete everything related to the student", async () => { + personORMMock.deletePersonFromDB.mockResolvedValue(); + + const student = { + student_id: 0, + person_id: 0, + gender: "", + pronouns: "", + phone_number: "", + nickname: "", + alumni: false, + }; + prismaMock.student.findUnique.mockResolvedValue(student); + await deleteStudentFromDB(0); + + expect(personORMMock.deletePersonFromDB).toBeCalledTimes(1); + expect(prismaMock.student.findUnique).toBeCalledTimes(1); + + personORMMock.deletePersonFromDB.mockReset(); +}); + test("should return all the people with the selected gender", async () => { prismaMock.student.findMany.mockResolvedValue([response]); await expect(searchStudentByGender("female")).resolves.toEqual([response]); }); + +test("should return the students that succeed to the filtered fields", async () => { + const returnval = [ + { + student_id: 0, + person_id: 0, + gender: "", + pronouns: "", + phone_number: "", + nickname: "", + alumni: false, + }, + ]; + + prismaMock.student.findMany.mockResolvedValue(returnval); + await expect( + filterStudents( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + [""], + undefined, + undefined, + undefined, + 2022, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ data: [], pagination: { count: 0, page: 0 } }); +}); + +test("should return the students that succeed to the filtered fields but with a status filter", async () => { + const returnval = [ + { + student_id: 0, + person_id: 0, + gender: "", + pronouns: "", + phone_number: "", + nickname: "", + alumni: false, + }, + ]; + + prismaMock.student.findMany.mockResolvedValue(returnval); + + await expect( + filterStudents( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + [""], + undefined, + undefined, + decision_enum.MAYBE, + 2022, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ data: [], pagination: { count: 0, page: 0 } }); +}); + +test("should return the students that succeed to the filtered fields but with a status filter", async () => { + const returnval = [ + { + student_id: 0, + person_id: 0, + gender: "", + pronouns: "", + phone_number: "", + nickname: "", + alumni: false, + }, + ]; + + prismaMock.student.findMany.mockResolvedValue(returnval); + + await expect( + filterStudents( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + [""], + undefined, + undefined, + decision_enum.MAYBE, + undefined, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ + data: [ + { + alumni: false, + gender: "", + nickname: "", + person_id: 0, + phone_number: "", + pronouns: "", + student_id: 0, + }, + ], + pagination: { count: undefined, page: 0 }, + }); +}); + +test("should return the students that succeed to the filtered fields but with a status filter", async () => { + const returnval = [ + { + student_id: 0, + person_id: 0, + gender: "", + pronouns: "", + phone_number: "", + nickname: "", + alumni: false, + }, + ]; + + const user_response = { + session_id: "50", + login_user_id: 1, + person_id: 0, + password: "password", + is_admin: false, + is_coach: false, + session_keys: ["key1", "key2"], + account_status: account_status_enum.DISABLED, + login_user_osoc: [ + { + osoc: { + year: 2022, + }, + }, + ], + }; + + prismaMock.student.findMany.mockResolvedValue(returnval); + prismaMock.login_user.findUnique.mockResolvedValue(user_response); + + await expect( + filterStudents( + { currentPage: 0, pageSize: 25 }, + undefined, + undefined, + [""], + undefined, + undefined, + undefined, + 2022, + undefined, + undefined, + undefined, + 0 + ) + ).resolves.toEqual({ + data: [ + { + alumni: false, + gender: "", + nickname: "", + person_id: 0, + phone_number: "", + pronouns: "", + student_id: 0, + }, + ], + pagination: { count: undefined, page: 0 }, + }); +}); + +test("should return a list with the applied years", async () => { + const val = { + job_application: [ + { + osoc: { + year: 2022, + }, + }, + { + osoc: { + year: 2023, + }, + }, + ], + student_id: 0, + person_id: 0, + gender: "", + pronouns: "", + phone_number: "", + nickname: "", + alumni: false, + }; + + prismaMock.student.findUnique.mockResolvedValue(val); + await expect(getAppliedYearsForStudent(0)).resolves.toEqual([2022, 2023]); +}); + +test("should return the empty list of visible years because the student does not exist", async () => { + prismaMock.student.findUnique.mockResolvedValue(null); + await expect(getAppliedYearsForStudent(0)).resolves.toEqual([]); +}); diff --git a/backend/tests/orm_unit/template.test.ts b/backend/tests/orm_unit/template.test.ts new file mode 100644 index 00000000..eefad446 --- /dev/null +++ b/backend/tests/orm_unit/template.test.ts @@ -0,0 +1,67 @@ +import { prismaMock } from "./singleton"; +import { + createTemplate, + deleteTemplate, + getAllTemplates, + getTemplateById, + getTemplatesByName, + updateTemplate, +} from "../../orm_functions/template"; + +const template = { + template_email_id: 0, + owner_id: 0, + name: "", + content: "", + subject: "", + cc: "", +}; + +test("should return a list of all templates", async () => { + const expected = [template]; + prismaMock.template_email.findMany.mockResolvedValue(expected); + await expect(getAllTemplates()).resolves.toEqual(expected); +}); + +test("should return the template with the given id", async () => { + prismaMock.template_email.findUnique.mockResolvedValue(template); + await expect(getTemplateById(0)).resolves.toEqual(template); +}); + +test("should return the templates with the given name", async () => { + const expected = [template]; + prismaMock.template_email.findMany.mockResolvedValue(expected); + await expect(getTemplatesByName("name")).resolves.toEqual(expected); +}); + +test("should return the created template", async () => { + prismaMock.template_email.create.mockResolvedValue(template); + await expect( + createTemplate({ + ownerId: 0, + name: "", + content: "", + cc: "", + subject: "", + }) + ).resolves.toEqual(template); +}); + +test("should return the updated template", async () => { + prismaMock.template_email.update.mockResolvedValue(template); + await expect( + updateTemplate({ + templateId: 0, + ownerId: 0, + name: "", + content: "", + cc: "", + subject: "", + }) + ).resolves.toEqual(template); +}); + +test("should delete the template with the given id", async () => { + prismaMock.template_email.delete.mockResolvedValue(template); + await expect(deleteTemplate(0)).resolves.toEqual(template); +}); diff --git a/backend/tests/request.test.ts b/backend/tests/request.test.ts index 788c52d2..633d541c 100644 --- a/backend/tests/request.test.ts +++ b/backend/tests/request.test.ts @@ -5,11 +5,33 @@ import * as config from "../config.json"; import * as Rq from "../request"; import * as T from "../types"; import { errors } from "../utility"; +import { allNonNaN, idIsNumber } from "../request"; function setSessionKey(req: express.Request, key: string): void { req.headers.authorization = config.global.authScheme + " " + key; } +test("Id is number tests", () => { + expect( + allNonNaN(["year", "id"], { year: 2022, id: 2 }) + ).resolves.toStrictEqual({ year: 2022, id: 2 }); + const noNumber = parseInt("id"); + expect( + allNonNaN(["year", "id"], { year: 2022, id: noNumber }) + ).rejects.toBe(errors.cookArgumentError()); +}); + +test("Ids are numbers tests", () => { + expect(idIsNumber({ id: 1, sessionkey: "key" })).resolves.toStrictEqual({ + id: 1, + sessionkey: "key", + }); + const noNumber = parseInt("id"); + expect(idIsNumber({ id: noNumber, sessionkey: "key" })).rejects.toBe( + errors.cookArgumentError() + ); +}); + test("Can parse Key-only requests", () => { const valid: express.Request = getMockReq(); const invalid: express.Request = getMockReq(); @@ -23,11 +45,9 @@ test("Can parse Key-only requests", () => { const calls = [ Rq.parseLogoutRequest, - Rq.parseStudentAllRequest, Rq.parseCoachAllRequest, Rq.parseGetAllCoachRequestsRequest, Rq.parseAdminAllRequest, - Rq.parseProjectAllRequest, Rq.parseConflictAllRequest, Rq.parseFollowupAllRequest, Rq.parseTemplateListRequest, @@ -67,7 +87,6 @@ test("Can parse Key-ID requests", () => { onlyid.params.id = res.id.toString(); const calls = [ - Rq.parseSingleStudentRequest, Rq.parseDeleteStudentRequest, Rq.parseSingleCoachRequest, Rq.parseDeleteCoachRequest, @@ -102,6 +121,75 @@ test("Can parse Key-ID requests", () => { return Promise.all([successes, failures, otherfails].flat()); }); +test("Can parse pagination requests", () => { + const valid: express.Request = getMockReq(); + const valid_invpgsz: express.Request = getMockReq(); + const valid_pgsz: express.Request = getMockReq(); + const invalid: express.Request = getMockReq(); + const wrongprop: express.Request = getMockReq(); + const validPg: express.Request = getMockReq(); + + setSessionKey(valid, "hello I am a key"); + setSessionKey(validPg, "hello I am a key"); + setSessionKey(valid_invpgsz, "hello I am a key"); + setSessionKey(valid_pgsz, "hello I am a key"); + wrongprop.body.key = "hello I am a key as well"; + validPg.body.currentPage = 5; + valid_invpgsz.body.currentPage = 5; + valid_pgsz.body.currentPage = 5; + valid_invpgsz.body.pageSize = "String"; + valid_pgsz.body.pageSize = 5; + const size = config.global.pageSize; + + const calls = [ + Rq.parseStudentAllRequest, + Rq.parseProjectAllRequest, + Rq.parseUserAllRequest, + ]; + + const successes = calls.map((call) => + expect(call(valid)).resolves.toStrictEqual({ + sessionkey: "hello I am a key", + currentPage: 0, + pageSize: size, + }) + ); + + const paged = calls.map((call) => + expect(call(validPg)).resolves.toStrictEqual({ + sessionkey: "hello I am a key", + currentPage: 5, + pageSize: size, + }) + ); + + const paged_invpgsz = calls.map((call) => + expect(call(valid_invpgsz)).resolves.toStrictEqual({ + sessionkey: "hello I am a key", + currentPage: 5, + pageSize: size, + }) + ); + + const paged_pgsz = calls.map((call) => + expect(call(valid_pgsz)).resolves.toStrictEqual({ + sessionkey: "hello I am a key", + currentPage: 5, + pageSize: 5, + }) + ); + + const failures = calls + .flatMap((call) => [call(invalid), call(wrongprop)]) + .map((sub) => + expect(sub).rejects.toStrictEqual(errors.cookUnauthenticated()) + ); + + return Promise.all( + [successes, paged, failures, paged_invpgsz, paged_pgsz].flat() + ); +}); + test("Can parse update login user requests", () => { const id = 1234; const key = "abc"; @@ -167,11 +255,14 @@ test("Can parse login request", () => { const valid: express.Request = getMockReq(); const noname: express.Request = getMockReq(); const nopass: express.Request = getMockReq(); + const unvalid: express.Request = getMockReq(); valid.body.name = "Alice.STUDENT@hotmail.be"; valid.body.pass = "Pass #1"; noname.body.pass = "Pass #2"; nopass.body.name = "Name.2@email.be"; + unvalid.body.pass = "Pass #2"; + unvalid.body.name = "Name.email.be"; // TODO return Promise.all([ @@ -185,6 +276,9 @@ test("Can parse login request", () => { expect(Rq.parseLoginRequest(nopass)).rejects.toBe( errors.cookArgumentError() ), + expect(Rq.parseLoginRequest(unvalid)).rejects.toBe( + errors.cookArgumentError() + ), ]); }); @@ -193,8 +287,7 @@ test("Can parse update student request", () => { const dataV: T.Anything = { emailOrGithub: "ab@c.de", alumni: false, - firstName: "ab c", - lastName: "", + name: "ab c", gender: "Apache Attack Helicopter", pronouns: "vroom/vroom", phone: "+32420 696969", @@ -209,7 +302,7 @@ test("Can parse update student request", () => { const failure1: T.Anything = { emailOrGithub: "ab@c.de", - firstName: "ab", // no last name + name: "ab", gender: "Apache Attack Helicopter", pronouns: "vroom/vroom", phone: "+32420 696969", @@ -223,8 +316,7 @@ test("Can parse update student request", () => { const failure2: T.Anything = { emailOrGithub: "ab@c.de", - firstName: "ab c", - lastName: "", + name: "ab c", gender: "Apache Attack Helicopter", pronouns: "vroom/vroom", phone: "+32420 696969", @@ -260,7 +352,6 @@ test("Can parse update student request", () => { dataV.id = id; dataV.sessionkey = sessionkey; failure1.id = id; - failure1.lastName = undefined; failure1.alumni = undefined; failure1.nickname = undefined; failure1.sessionkey = sessionkey; @@ -291,15 +382,17 @@ test("Can parse update student request", () => { test("Can parse suggest student request", () => { const key = "my-session-key"; const id = 9845; - const ys: T.Anything = { suggestion: "YES" }; - const mb: T.Anything = { suggestion: "MAYBE" }; - const no: T.Anything = { suggestion: "NO" }; + const ys: T.Anything = { suggestion: "YES", job_application_id: 1 }; + const mb: T.Anything = { suggestion: "MAYBE", job_application_id: 1 }; + const no: T.Anything = { suggestion: "NO", job_application_id: 1 }; const nr: T.Anything = { suggestion: "NO", reason: "I just don't like you", + job_application_id: 1, }; - const i1: T.Anything = { suggestion: "TOMORROW" }; - const i2: T.Anything = { suggestion: "no" }; // no caps + const i1: T.Anything = { suggestion: "TOMORROW", job_application_id: 1 }; + const i2: T.Anything = { suggestion: "no", job_application_id: 1 }; // no caps + const i3: T.Anything = { suggestion: "NO" }; // no job application id const okays = [ys, mb, no, nr].map((x) => { const copy: T.Anything = { ...x }; @@ -319,7 +412,7 @@ test("Can parse suggest student request", () => { ).resolves.toStrictEqual(copy); }); - const fails = [i1, i2].map((x) => { + const fails = [i1, i2, i3].map((x) => { const req: express.Request = getMockReq(); req.params.id = id.toString(); req.body = { ...x }; @@ -332,21 +425,508 @@ test("Can parse suggest student request", () => { return Promise.all([okays, fails].flat()); }); -// TODO test Rq.parseAcceptNewUserRequest -// TODO test Rq.parseGetSuggestionsStudentRequest +test("Can parse get suggestions request", () => { + const key = "my-session-key"; + const id = 9845; + + const noYear: T.Anything = {}; + const year: T.Anything = { year: 2022 }; + + const i1: T.Anything = { year: 2022 }; + + const okays = [noYear, year].map((x) => { + const copy: T.Anything = { ...x }; + copy.id = id; + const req: express.Request = getMockReq(); + req.params.id = id.toString(); + req.body = x; + setSessionKey(req, key); + copy.sessionkey = key; + return expect( + Rq.parseGetSuggestionsStudentRequest(req) + ).resolves.toStrictEqual(copy); + }); + + const fails = [i1].map((x) => { + const req: express.Request = getMockReq(); + req.body = { ...x }; + setSessionKey(req, key); + return expect(Rq.parseSuggestStudentRequest(req)).rejects.toBe( + errors.cookArgumentError() + ); + }); + + return Promise.all([okays, fails].flat()); +}); + +test("Can parse get student request", () => { + const key = "my-session-key"; + const id = 9845; + + const noYear: T.Anything = {}; + const year: T.Anything = { year: 2022 }; + + const i1: T.Anything = { year: 2022 }; + + const okays = [noYear, year].map((x) => { + const copy: T.Anything = { ...x }; + copy.id = id; + const req: express.Request = getMockReq(); + req.params.id = id.toString(); + req.body = x; + setSessionKey(req, key); + copy.sessionkey = key; + return expect(Rq.parseSingleStudentRequest(req)).resolves.toStrictEqual( + copy + ); + }); + + const fails = [i1].map((x) => { + const req: express.Request = getMockReq(); + req.body = { ...x }; + setSessionKey(req, key); + return expect(Rq.parseSingleStudentRequest(req)).rejects.toBe( + errors.cookArgumentError() + ); + }); + + return Promise.all([okays, fails].flat()); +}); + +test("Can parse filter osocs request", () => { + const key = "my-session-key"; + + const nothing = {}; + const yearFilterOnly = { yearFilter: 2022 }; + const yearSortOnly1 = { yearSort: "asc" }; + const yearSortOnly2 = { yearSort: "desc" }; + const yearFilterAndSort = { yearFilter: 2022, yearSort: "asc" }; + + const i1: T.Anything = { yearSort: "sort" }; + const i2: T.Anything = { yearFilter: 2022, yearSort: "sort" }; + const i3: T.Anything = { yearFilter: "year", yearSort: "asc" }; + + const okays = [ + nothing, + yearFilterOnly, + yearSortOnly1, + yearSortOnly2, + yearFilterAndSort, + ].map((x) => { + const copy: T.Anything = { ...x }; + const req: express.Request = getMockReq(); + req.body = x; + setSessionKey(req, key); + ["yearFilter", "yearSort"].forEach((x) => { + if (!(x in req.body)) { + copy[x] = undefined; + } + }); + copy.sessionkey = key; + return expect(Rq.parseFilterOsocsRequest(req)).resolves.toStrictEqual({ + ...copy, + currentPage: 0, + pageSize: config.global.pageSize, + }); + }); + + const fails = [i1, i2, i3].map((x) => { + const req: express.Request = getMockReq(); + req.body = { ...x }; + setSessionKey(req, key); + return expect(Rq.parseFilterOsocsRequest(req)).rejects.toBe( + errors.cookArgumentError() + ); + }); + + const unauth = [ + nothing, + yearFilterOnly, + yearSortOnly1, + yearSortOnly2, + yearFilterAndSort, + ].map((body) => { + const req: express.Request = getMockReq(); + req.body = { ...body }; + expect(Rq.parseFilterOsocsRequest(req)).rejects.toBe( + errors.cookUnauthenticated() + ); + }); + + return Promise.all([okays, fails, unauth].flat()); +}); + +test("Can parse filter students request", () => { + const key = "my-session-key"; + + const nothing = {}; + const osocYear: T.Requests.StudentFilterParameters = { osocYear: 2022 }; + const nameFilter: T.Requests.StudentFilterParameters = { + nameFilter: "Firstname", + }; + const emailFilterGoodEmail: T.Requests.StudentFilterParameters = { + emailFilter: "firstname.lastname@hotmail.com", + }; + const emailFilterBadEmail: T.Requests.StudentFilterParameters = { + emailFilter: "email", + }; + const roleFilterList: T.Requests.StudentFilterParameters = { + roleFilter: ["Frontend developer", "Backend developer"], + }; + const roleFilterString: T.Requests.StudentFilterParameters = { + roleFilter: "Frontend developer,Backend developer", + }; + const alumniFilterBoolean: T.Requests.StudentFilterParameters = { + alumniFilter: true, + }; + const alumniFilterString: T.Requests.StudentFilterParameters = { + alumniFilter: "true", + }; + const coachFilterBoolean: T.Requests.StudentFilterParameters = { + coachFilter: true, + }; + const coachFilterString: T.Requests.StudentFilterParameters = { + coachFilter: "true", + }; + const statusFilter: T.Requests.StudentFilterParameters = { + statusFilter: "YES", + }; + const emailStatusFilter: T.Requests.StudentFilterParameters = { + emailStatusFilter: "APPROVED", + }; + const nameSort: T.Requests.StudentFilterParameters = { + nameSort: "asc", + }; + const emailSort: T.Requests.StudentFilterParameters = { emailSort: "desc" }; + + const wrongStatus: T.Anything = { statusFilter: "damn" }; + const wrongEmailStatus: T.Anything = { emailStatusFilter: "email status" }; + const wrongNameSort: T.Anything = { nameSort: "firstname" }; + const wrongEmailSort: T.Anything = { emailSort: "email" }; + const wrongAlumniFilter: T.Anything = { alumniFilter: "is_admin filter" }; + const wrongCoachFilter: T.Anything = { coachFilter: "is_coach filter" }; + const wrongOsocYear: T.Anything = { osocYear: "year" }; + + const okays = [ + [nothing, nothing], + [osocYear, osocYear], + [nameFilter, nameFilter], + [emailFilterGoodEmail, emailFilterGoodEmail], + [emailFilterBadEmail, emailFilterBadEmail], + [roleFilterList, roleFilterList], + [alumniFilterBoolean, alumniFilterBoolean], + [coachFilterBoolean, coachFilterBoolean], + [statusFilter, statusFilter], + [emailStatusFilter, emailStatusFilter], + [nameSort, nameSort], + [emailSort, emailSort], + [roleFilterString, roleFilterList], + [alumniFilterString, alumniFilterBoolean], + [coachFilterString, coachFilterBoolean], + ].map((x) => { + const copy: T.Anything = { ...x[1] }; + const req: express.Request = getMockReq(); + req.body = x[0]; + setSessionKey(req, key); + [ + "nameFilter", + "emailFilter", + "alumniFilter", + "coachFilter", + "statusFilter", + "emailStatusFilter", + "nameSort", + "roleFilter", + "emailSort", + ].forEach((v) => { + if (!(v in req.body)) { + copy[v] = undefined; + } + }); + + copy.currentPage = 0; + copy.pageSize = config.global.pageSize; + + if (!("osocYear" in req.body)) { + copy["osocYear"] = undefined; + } + copy.sessionkey = key; + return expect( + Rq.parseFilterStudentsRequest(req) + ).resolves.toStrictEqual(copy); + }); + + const fails = [ + wrongStatus, + wrongNameSort, + wrongEmailSort, + wrongEmailStatus, + wrongAlumniFilter, + wrongCoachFilter, + wrongOsocYear, + ].map((x) => { + const req: express.Request = getMockReq(); + req.body = { ...x }; + setSessionKey(req, key); + return expect(Rq.parseFilterStudentsRequest(req)).rejects.toBe( + errors.cookArgumentError() + ); + }); + + const unauth = [ + nothing, + osocYear, + nameFilter, + emailFilterGoodEmail, + emailFilterBadEmail, + roleFilterList, + alumniFilterBoolean, + coachFilterBoolean, + statusFilter, + emailStatusFilter, + nameSort, + emailSort, + roleFilterString, + alumniFilterString, + coachFilterString, + ].map((body) => { + const req: express.Request = getMockReq(); + req.body = { ...body }; + return expect(Rq.parseFilterStudentsRequest(req)).rejects.toBe( + errors.cookUnauthenticated() + ); + }); + + return Promise.all([okays, fails, unauth].flat()); +}); + +test("Can parse filter users request", () => { + const key = "my-session-key"; + + const nothing = {}; + const emailFilterGoodEmail = { + emailFilter: "firstname.lastname@hotmail.com", + }; + const emailFilterBadEmail = { + emailFilter: "email", + }; + const isAdminFilterBoolean = { + isAdminFilter: true, + }; + const isAdminFilterString = { + isAdminFilter: "true", + }; + const isCoachFilterBoolean = { + isCoachFilter: true, + }; + const isCoachFilterString = { + isCoachFilter: "true", + }; + const statusFilter = { + statusFilter: "ACTIVATED", + }; + const nameFilter = { + nameFilter: "Name", + }; + const nameSort = { + nameSort: "asc", + }; + const emailSort = { + emailSort: "asc", + }; + + const wrongStatus: T.Anything = { statusFilter: "status" }; + const wrongIsAdmin: T.Anything = { isAdminFilter: "is_admin filter" }; + const wrongIsCoach: T.Anything = { isCoachFilter: "is_coach filter" }; + const wrongNameSort: T.Anything = { nameSort: "lastname" }; + const wrongEmailSort: T.Anything = { emailSort: "email" }; + + const okays = [ + [nothing, nothing], + [isAdminFilterString, isAdminFilterBoolean], + [isCoachFilterString, isCoachFilterBoolean], + [nameFilter, nameFilter], + [emailFilterGoodEmail, emailFilterGoodEmail], + [emailFilterBadEmail, emailFilterBadEmail], + [nameSort, nameSort], + [statusFilter, statusFilter], + [emailSort, emailSort], + ].map((x) => { + const copy: T.Anything = { ...x[1] }; + const req: express.Request = getMockReq(); + req.body = x[0]; + setSessionKey(req, key); + [ + "isAdminFilter", + "isCoachFilter", + "nameFilter", + "emailFilter", + "nameSort", + "statusFilter", + "emailSort", + ].forEach((x) => { + if (!(x in req.body)) { + copy[x] = undefined; + } + }); + copy.sessionkey = key; + copy.currentPage = 0; + copy.pageSize = config.global.pageSize; + return expect(Rq.parseFilterUsersRequest(req)).resolves.toStrictEqual( + copy + ); + }); + + const fails = [ + wrongStatus, + wrongIsAdmin, + wrongIsCoach, + wrongNameSort, + wrongEmailSort, + ].map((x) => { + const req: express.Request = getMockReq(); + req.body = { ...x }; + setSessionKey(req, key); + return expect(Rq.parseFilterUsersRequest(req)).rejects.toBe( + errors.cookArgumentError() + ); + }); + + const unauth = [ + nothing, + isAdminFilterString, + isCoachFilterString, + nameFilter, + emailFilterGoodEmail, + emailFilterBadEmail, + nameSort, + statusFilter, + emailSort, + ].map((x) => { + const req: express.Request = getMockReq(); + req.body = { ...x }; + return expect(Rq.parseFilterUsersRequest(req)).rejects.toBe( + errors.cookUnauthenticated() + ); + }); + + return Promise.all([okays, fails, unauth].flat()); +}); + +test("Can parse filter projects request", () => { + const key = "my-session-key"; + + const nothing = {}; + const projectNameFilter = { + projectNameFilter: "Project name", + }; + const clientNameFilter = { + clientNameFilter: "Client name", + }; + const fullyAssignedFilterString = { + fullyAssignedFilter: "true", + }; + const fullyAssignedFilterBoolean = { + fullyAssignedFilter: true, + }; + const osocYear = { + osocYear: 2022, + }; + const projectNameSort = { + projectNameSort: "asc", + }; + const clientNameSort = { + clientNameSort: "asc", + }; + + const wrongFullyAssignedFilter: T.Anything = { + fullyAssignedFilter: "Fully assigned filter", + }; + const wrongProjectNameSort: T.Anything = { + projectNameSort: "Project name sort", + }; + const wrongClientNameSort: T.Anything = { + clientNameSort: "Client name sort", + }; + + const okays = [ + [nothing, nothing], + [fullyAssignedFilterString, fullyAssignedFilterBoolean], + [projectNameFilter, projectNameFilter], + [clientNameFilter, clientNameFilter], + [osocYear, osocYear], + [projectNameSort, projectNameSort], + [clientNameSort, clientNameSort], + ].map((x) => { + const copy: T.Anything = { ...x[1] }; + const req: express.Request = getMockReq(); + req.body = x[0]; + setSessionKey(req, key); + [ + "projectNameFilter", + "clientNameFilter", + "fullyAssignedFilter", + "osocYear", + "projectNameSort", + "clientNameSort", + ].forEach((x) => { + if (!(x in req.body)) { + copy[x] = undefined; + } + }); + copy.sessionkey = key; + copy.currentPage = 0; + copy.pageSize = config.global.pageSize; + return expect( + Rq.parseFilterProjectsRequest(req) + ).resolves.toStrictEqual(copy); + }); + + const fails = [ + wrongFullyAssignedFilter, + wrongProjectNameSort, + wrongClientNameSort, + ].map((x) => { + const req: express.Request = getMockReq(); + req.body = { ...x }; + setSessionKey(req, key); + return expect(Rq.parseFilterProjectsRequest(req)).rejects.toBe( + errors.cookArgumentError() + ); + }); + + const unauth = [ + nothing, + fullyAssignedFilterString, + projectNameFilter, + clientNameFilter, + osocYear, + projectNameSort, + clientNameSort, + ].map((body) => { + const req: express.Request = getMockReq(); + req.body = { ...body }; + expect(Rq.parseFilterProjectsRequest(req)).rejects.toBe( + errors.cookUnauthenticated() + ); + }); + + return Promise.all([okays, fails, unauth].flat()); +}); test("Can parse final decision request", () => { const key = "key"; const id = 6969420420; - const data: T.Anything = {}; - const dat2: T.Anything = { reply: "YES" }; - const dat3: T.Anything = { reply: "NO" }; - const dat4: T.Anything = { reply: "MAYBE" }; - const dat5: T.Anything = { reply: "something" }; - const dat6: T.Anything = { reply: "maybe" }; - const dat7: T.Anything = { reply: "YES" }; - - const p = [data, dat2, dat3, dat4].map((x) => { + const noData: T.Anything = {}; + const dat2: T.Anything = { reply: "YES", job_application_id: 1 }; + const dat3: T.Anything = { reply: "NO", job_application_id: 1 }; + const dat4: T.Anything = { reply: "MAYBE", job_application_id: 1 }; + const dat5: T.Anything = { reply: "something", job_application_id: 1 }; + const dat6: T.Anything = { reply: "maybe", job_application_id: 1 }; + const dat7: T.Anything = { reply: "YES", job_application_id: 1 }; + const dat8: T.Anything = { reply: "YES" }; + + const p = [dat2, dat3, dat4].map((x) => { const r: express.Request = getMockReq(); r.body = { ...x }; r.params.id = id.toString(); @@ -361,7 +941,7 @@ test("Can parse final decision request", () => { ).resolves.toStrictEqual(x); }); - const q = [dat5, dat6].map((x) => { + const q = [noData, dat5, dat6, dat8].map((x) => { const r: express.Request = getMockReq(); r.body = { ...x }; r.params.id = id.toString(); @@ -387,15 +967,13 @@ test("Can parse final decision request", () => { test("Can parse coach access request", () => { const r1: T.Anything = { - firstName: "Jeff Georgette", - lastName: "", + name: "Jeff Georgette", email: "idonthavegithub@git.hub", pass: "thisismypassword", }; const r2: T.Anything = { - firstName: "Jeff Georgette", - lastName: "", + name: "Jeff Georgette", email: "idonthavegithub@git.hub", }; @@ -403,21 +981,17 @@ test("Can parse coach access request", () => { req1.body = { ...r1 }; const req2: express.Request = getMockReq(); - r2.pass = undefined; req2.body = { ...r2 }; const req3: express.Request = getMockReq(); req3.body = {}; - console.log(Rq.parseRequestUserRequest(req1)); - console.log(r1); - const prom1: Promise = expect( Rq.parseRequestUserRequest(req1) ).resolves.toStrictEqual(r1); const prom2: Promise = expect( Rq.parseRequestUserRequest(req2) - ).resolves.toStrictEqual(r2); + ).rejects.toBe(errors.cookArgumentError()); const prom3: Promise = expect( Rq.parseRequestUserRequest(req3) ).rejects.toBe(errors.cookArgumentError()); @@ -432,8 +1006,21 @@ test("Can parse new project request", () => { partner: "Simic Combine", start: Date.now(), end: Date.now(), - positions: 69, osocId: 17, + description: "Project description", + roles: { + roles: [ + { + name: "role1", + positions: 4, + }, + { + name: "role2", + positions: 6, + }, + ], + }, + coaches: [1, 2], }; const d2: T.Anything = {}; const d3: T.Anything = { @@ -441,7 +1028,6 @@ test("Can parse new project request", () => { partner: "Simic Combine", start: Date.now(), end: Date.now(), - positions: 420, }; const req1: express.Request = getMockReq(); @@ -475,23 +1061,47 @@ test("Can parse update project request", () => { const d1: T.Anything = { name: "Experiment One", partner: "Simic Combine", + description: "Project description", start: Date.now(), end: Date.now(), - positions: 69, + roles: { + roles: [ + { + id: 5, + positions: 4, + }, + { + id: 2, + positions: 6, + }, + ], + }, + addCoaches: { + coaches: [2, 3], + }, + removeCoaches: { + coaches: [1], + }, }; const d2: T.Anything = {}; const d3: T.Anything = { name: "Experiment One", partner: "Simic Combine", + description: "Project description", start: Date.now(), - positions: 420, }; const d4: T.Anything = { name: "Experiment One", partner: "Simic Combine", start: Date.now(), end: Date.now(), - positions: 69, + }; + const d5: T.Anything = { + name: "Experiment One", + partner: "Simic Combine", + description: "Project description", + start: Date.now(), + end: Date.now(), }; const req1: express.Request = getMockReq(); @@ -499,6 +1109,7 @@ test("Can parse update project request", () => { const req3: express.Request = getMockReq(); const req4: express.Request = getMockReq(); const req5: express.Request = getMockReq(); + const req6: express.Request = getMockReq(); req1.body = { ...d1 }; req1.params.id = id.toString(); @@ -513,6 +1124,9 @@ test("Can parse update project request", () => { req4.params.id = id.toString(); req5.body = { ...d1 }; setSessionKey(req5, key); + req6.body = { ...d5 }; + req6.params.id = id.toString(); + setSessionKey(req6, key); d1.id = id; d1.sessionkey = key; @@ -520,7 +1134,15 @@ test("Can parse update project request", () => { d3.id = id; d3.sessionkey = key; d3.end = undefined; + d3.addCoaches = undefined; + d3.removeCoaches = undefined; + d3.roles = undefined; d4.id = id; + d5.id = id; + d5.sessionkey = key; + d5.removeCoaches = undefined; + d5.roles = undefined; + d5.addCoaches = undefined; const p1: Promise = expect( Rq.parseUpdateProjectRequest(req1) @@ -537,8 +1159,11 @@ test("Can parse update project request", () => { const p5: Promise = expect( Rq.parseUpdateProjectRequest(req5) ).rejects.toBe(errors.cookArgumentError()); + const p6: Promise = expect( + Rq.parseUpdateProjectRequest(req6) + ).resolves.toStrictEqual(d5); - return Promise.all([p1, p2, p3, p4, p5]); + return Promise.all([p1, p2, p3, p4, p5, p6]); }); test("Can parse draft student request", () => { @@ -546,11 +1171,12 @@ test("Can parse draft student request", () => { const id = 89846; const d1: T.Anything = { - studentId: "im-a-student", + studentId: 486453, role: "the useless one", + jobApplicationId: 0, }; - const d2: T.Anything = { studentId: "im-a-student" }; - const d3: T.Anything = { studentId: "im-a-student", role: "the lazy one" }; + const d2: T.Anything = { studentId: 486453, jobApplicationId: 0 }; + const d3: T.Anything = { studentId: 486453, role: "the lazy one" }; const r1: express.Request = getMockReq(); const r2: express.Request = getMockReq(); @@ -594,15 +1220,16 @@ test("Can parse mark as followed up request", () => { const key = "my-key-arrived-but"; const id = 78945312; - const sc: T.Anything = { type: "SCHEDULED" }; - const st: T.Anything = { type: "SENT" }; - const fl: T.Anything = { type: "FAILED" }; - const no: T.Anything = { type: "NONE" }; - const dr: T.Anything = { type: "DRAFT" }; + const sc: T.Anything = { type: "APPLIED" }; + const st: T.Anything = { type: "AWAITING_PROJECT" }; + const fl: T.Anything = { type: "APPROVED" }; + const no: T.Anything = { type: "CONTRACT_CONFIRMED" }; + const dr: T.Anything = { type: "CONTRACT_DECLINED" }; + const rj: T.Anything = { type: "REJECTED" }; const i1: T.Anything = { type: "invalid" }; const i3: T.Anything = {}; - const okays = [sc, st, fl, no, dr].map((x) => { + const okays = [sc, st, fl, no, dr, rj].map((x) => { const r: express.Request = getMockReq(); r.body = { ...x }; setSessionKey(r, key); @@ -793,6 +1420,203 @@ test("Can parse update template request", () => { return Promise.all([okays, fails1, fails2, fails3].flat()); }); +test("Can parse reset requests", () => { + const v1: T.Anything = { email: "bob.student@gmail.com" }; + + const req1: express.Request = getMockReq(); + req1.body = { ...v1 }; + const normalizedEmail: { email: string } = { + email: "bobstudent@gmail.com", + }; + + const valid = expect( + Rq.parseRequestResetRequest(req1) + ).resolves.toStrictEqual(normalizedEmail); + + const i1: T.Anything = { email: "bob" }; + + const req2: express.Request = getMockReq(); + req2.body = { ...i1 }; + + const invalid = expect(Rq.parseRequestResetRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + +test("Can parse check reset code requests", () => { + const id = 0; + + const req: express.Request = getMockReq(); + req.params.id = id.toString(); + + const valid = expect( + Rq.parseCheckResetCodeRequest(req) + ).resolves.toStrictEqual({ code: id.toString() }); + + const req2: express.Request = getMockReq(); + + const invalid = expect(Rq.parseCheckResetCodeRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + +test("Can parse reset password requests", () => { + const id = 0; + const password: { password: string } = { password: "pass" }; + + const req: express.Request = getMockReq(); + req.params.id = id.toString(); + req.body = { ...password }; + + const valid = expect( + Rq.parseResetPasswordRequest(req) + ).resolves.toStrictEqual({ + code: id.toString(), + password: password.password, + }); + + const req2: express.Request = getMockReq(); + req2.body = { ...password }; + + const invalid1 = expect(Rq.parseResetPasswordRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + const req3: express.Request = getMockReq(); + req2.params.id = id.toString(); + + const invalid2 = expect(Rq.parseCheckResetCodeRequest(req3)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid1, invalid2]); +}); + +test("Can parse student role request", () => { + const key = "my-key-arrived-but"; + + const name: T.Anything = { name: "name" }; + const noName: T.Anything = {}; + + const req: express.Request = getMockReq(); + req.body = { ...name }; + setSessionKey(req, key); + name.sessionkey = key; + const valid = expect( + Rq.parseStudentRoleRequest(req) + ).resolves.toStrictEqual(name); + + const req2: express.Request = getMockReq(); + req2.body = { ...noName }; + setSessionKey(req2, key); + const invalid = expect(Rq.parseStudentRoleRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + +test("Can parse remove assignee request", () => { + const key = "my-key-arrived-but"; + const id = 987465327465; + + const studentId: T.Anything = { student: 1 }; + const noStudentId: T.Anything = {}; + + const req: express.Request = getMockReq(); + req.body = { ...studentId }; + req.params.id = id.toString(); + setSessionKey(req, key); + studentId.id = id; + studentId.sessionkey = key; + + const valid = expect( + Rq.parseRemoveAssigneeRequest(req) + ).resolves.toStrictEqual({ + sessionkey: studentId.sessionkey, + studentId: studentId.student, + id: studentId.id, + }); + + const req2: express.Request = getMockReq(); + req2.body = { ...noStudentId }; + req2.params.id = id.toString(); + setSessionKey(req2, key); + studentId.id = id; + studentId.sessionkey = key; + + const invalid = expect(Rq.parseRemoveAssigneeRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + +test("Can parse accept new user request", () => { + const key = "my-key-arrived-but"; + const id = 987465327465; + + const v1: T.Anything = { is_admin: true, is_coach: true }; + + const i1: T.Anything = { is_admin: true }; + const i2: T.Anything = { is_coach: true }; + const i3: T.Anything = {}; + + const req1: express.Request = getMockReq(); + req1.body = { ...v1 }; + req1.params.id = id.toString(); + setSessionKey(req1, key); + v1.id = id; + v1.sessionkey = key; + + const valid = expect( + Rq.parseAcceptNewUserRequest(req1) + ).resolves.toStrictEqual(v1); + + const invalids = [i1, i2, i3].map((invalid) => { + const req2: express.Request = getMockReq(); + req2.body = { ...invalid }; + req2.params.id = id.toString(); + setSessionKey(req2, key); + invalid.id = id; + invalid.sessionkey = key; + + return expect(Rq.parseAcceptNewUserRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + }); + + return Promise.all([[valid], invalids].flat()); +}); + +test("Can parse new osoc edition request", () => { + const key = "my-key-arrived-but"; + + const year: T.Anything = { year: 2022 }; + const noYear: T.Anything = {}; + + const req: express.Request = getMockReq(); + req.body = { ...year }; + setSessionKey(req, key); + year.sessionkey = key; + const valid = expect( + Rq.parseNewOsocEditionRequest(req) + ).resolves.toStrictEqual(year); + + const req2: express.Request = getMockReq(); + req2.body = { ...noYear }; + setSessionKey(req2, key); + const invalid = expect(Rq.parseNewOsocEditionRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + test("Can parse self-modify requests", () => { const key = "Im bobs secret key, dont tell anyone"; const v1: T.Anything = {}; @@ -836,3 +1660,184 @@ test("Can parse self-modify requests", () => { return Promise.all([valids, invalids, unauths].flat()); }); + +test("Can parse remove coach request", () => { + const r1: T.Anything = { + loginUserId: 1, + }; + + const res: T.Requests.IdRequest = { + sessionkey: "Hello I am a key", + id: 20123, + }; + + const req1: express.Request = getMockReq(); + req1.body = { ...r1 }; + + const req2: express.Request = getMockReq(); + req2.body = {}; + + setSessionKey(req1, res.sessionkey); + req1.params.id = res.id.toString(); + setSessionKey(req2, res.sessionkey); + req2.params.id = res.id.toString(); + + const prom1: Promise = expect( + Rq.parseRemoveCoachRequest(req1) + ).resolves.toStrictEqual({ + sessionkey: "Hello I am a key", + loginUserId: 1, + id: 20123, + }); + const prom2: Promise = expect( + Rq.parseRemoveCoachRequest(req2) + ).rejects.toBe(errors.cookArgumentError()); + + return Promise.all([prom1, prom2]); +}); + +test("Can parse remove coach request", () => { + const r1: T.Anything = { + loginUserId: 1, + }; + + const res: T.Requests.IdRequest = { + sessionkey: "Hello I am a key", + id: 20123, + }; + + const req1: express.Request = getMockReq(); + req1.body = { ...r1 }; + + const req2: express.Request = getMockReq(); + req2.body = {}; + + setSessionKey(req1, res.sessionkey); + req1.params.id = res.id.toString(); + setSessionKey(req2, res.sessionkey); + req2.params.id = res.id.toString(); + + const prom1: Promise = expect( + Rq.parseAssignCoachRequest(req1) + ).resolves.toStrictEqual({ + sessionkey: "Hello I am a key", + loginUserId: 1, + id: 20123, + }); + const prom2: Promise = expect( + Rq.parseAssignCoachRequest(req2) + ).rejects.toBe(errors.cookArgumentError()); + + return Promise.all([prom1, prom2]); +}); + +test("Can parse remove coach request", () => { + const key = "key"; + const id = 10; + + const r1: T.Anything = { loginUserId: 1 }; + const noProjectUser: T.Anything = {}; + + const req: express.Request = getMockReq(); + req.body = { ...r1 }; + req.params.id = id.toString(); + setSessionKey(req, key); + const valid = expect( + Rq.parseRemoveCoachRequest(req) + ).resolves.toStrictEqual({ + sessionkey: "key", + id: 10, + loginUserId: 1, + }); + + const req2: express.Request = getMockReq(); + req2.body = { ...noProjectUser }; + req.params.id = id.toString(); + setSessionKey(req2, key); + const invalid = expect(Rq.parseRemoveCoachRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + +test("Can parse assign coach request", () => { + const key = "key"; + const id = 10; + + const r1: T.Anything = { loginUserId: 1 }; + const noProjectUser: T.Anything = {}; + + const req: express.Request = getMockReq(); + req.body = { ...r1 }; + req.params.id = id.toString(); + setSessionKey(req, key); + const valid = expect( + Rq.parseAssignCoachRequest(req) + ).resolves.toStrictEqual({ + sessionkey: "key", + id: 10, + loginUserId: 1, + }); + + const req2: express.Request = getMockReq(); + req2.body = { ...noProjectUser }; + req.params.id = id.toString(); + setSessionKey(req2, key); + const invalid = expect(Rq.parseAssignCoachRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + +test("Can parse users permissions request", () => { + const key = "key"; + const id = 10; + + const r1: T.Anything = { osoc_id: 1, login_user_id: 1 }; + const empty: T.Anything = {}; + + const req: express.Request = getMockReq(); + req.body = { ...r1 }; + req.params.id = id.toString(); + setSessionKey(req, key); + const valid = expect( + Rq.parseUsersPermissionsRequest(req) + ).resolves.toStrictEqual({ + sessionkey: "key", + id: 10, + osoc_id: 1, + login_user_id: 1, + }); + + const req2: express.Request = getMockReq(); + req2.body = { ...empty }; + req.params.id = id.toString(); + setSessionKey(req2, key); + const invalid = expect(Rq.parseUsersPermissionsRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ); + + return Promise.all([valid, invalid]); +}); + +test("Can parse get users permissions request", () => { + const key = "key"; + const id = 10; + + const empty: T.Anything = {}; + + const req: express.Request = getMockReq(); + req.body = { ...empty }; + req.params.id = id.toString(); + setSessionKey(req, key); + const valid = expect( + Rq.parseGetUserPermissionsRequest(req) + ).resolves.toStrictEqual({ + sessionkey: "key", + id: 10, + }); + + return Promise.all([valid]); +}); diff --git a/backend/tests/routes_integration/integr.ts b/backend/tests/routes_integration/integr.ts new file mode 100644 index 00000000..97443dc9 --- /dev/null +++ b/backend/tests/routes_integration/integr.ts @@ -0,0 +1,289 @@ +/* istanbul ignore file */ + +import * as supertest from "supertest"; +import * as server from "../../server"; +import * as ogConf from "../../config.json"; +import { Verb, ApiError } from "../../types"; +import { errors, generateKey } from "../../utility"; +import prisma from "../../prisma/prisma"; + +/** + * The type of the configuration for supertest requests + */ +export interface Config { + /** + * The configuration for the authentication scheme + */ + auth: { + /** + * Enable this part of the config? + */ + enable: boolean; + /** + * The type of authentication (the authentication scheme) + */ + type: string; + /** + * The value for the authentication (the actual session key, ...) + */ + value: string; + }; + /** + * The configuration for the Accept header + */ + accept: { + /** + * Enable this part of the config? + */ + enable: boolean; + /** + * The MIME type to accept (e.g. `application/json`) + */ + value: string; + }; +} + +/** + * The type of the request parameters (a dictionary of string to string) + */ +export interface RequestParams { + [key: string]: string; +} + +/** + * The type for the data to send in supertest requests + * @template T The type of data for the body + */ +export interface Data { + /** + * The request parameters (or URL parameters) to pass + */ + request?: RequestParams; + /** + * The body data to pass + */ + body?: T; +} + +/** + * The type for an expected Response + * @template T The type of data you expect to receive + */ +export interface Response { + /** + * The expected HTTP status code + */ + code: number; + /** + * The expected data in the body + */ + data: T; +} + +/** + * A default configuration. It is ready to accept a normal session key, and + * requests the server to return `application/json`. + */ +export const conf: Config = { + auth: { enable: true, type: ogConf.global.authScheme, value: "" }, + accept: { enable: true, value: "application/json" }, +}; + +/** + * Sets up a config authenticated with the given key. + * @param key The key to inject into the config. + * @param og An initial config. If this value is not given, use the default + * config. This value will never be modified (a copy will be returned). + * @param correctType Whether or not to set the correct authentication scheme. + * If this value is not given, use the default false (don't set the correct + * type). + * @returns A copy of the given config, where the key has been set. If no + * initial config is given, copies the default config. If `correctType == true`, + * also sets the correct authentication scheme. + */ +export function keyConf( + key: string, + og: Config = conf, + correctType = false +): Config { + const val = { ...og, auth: { ...conf.auth, value: key } }; + if (correctType) val.auth.type = ogConf.global.authScheme; + return val; +} + +/** + * Uses supertest to call the given endpoint. The returned value can be used as + * a Promise (which supports further testing). Upon awaiting, returns the result + * from supertest (which among others holds the response data and status code). + * @template T The type of data held in the body (can be undefined). + * @param verb The HTTP verb to use. + * @param ep The endpoint to call (should start with a leading `/`). + * @param data The data to pass (both request parameters and body data). + * @param config The configuration to use. If this parameter is not given, uses + * the default config. + * @returns The result from calling the given endpoint using supertest (a + * Promise-like object). + */ +export function endpoint( + verb: Verb, + ep: string, + data: Data, + config: Config = conf +) { + if (config == undefined) { + config = conf; + } + + if (data.request != undefined) { + ep += "?"; + for (const key in data.request) { + ep += + encodeURIComponent(key) + + "=" + + encodeURIComponent(data.request[key]) + + "&"; + } + } + + let intermediate = supertest.default(server.app)[verb](ep); + + if (config.accept.enable) { + intermediate = intermediate.set("Accept", config.accept.value); + } + + if (config.auth.enable) { + intermediate = intermediate.set( + "Authorization", + config.auth.type + " " + config.auth.value + ); + } + + if (data.body != undefined) { + return intermediate.send(data.body); + } + return intermediate.send(); +} + +/** + * Checks whether the given supertest result has the given status code + * (using jest), then returns the body of the result. This method will cause the + * surrounding jest test to fail if the HTTP code does not match. + * @param req The result from supertest. + * @param code The HTTP code you expect. + * @returns The body of the supertest result. + */ +export async function expectHttp(req: supertest.Test, code: number) { + const res = await req; + expect(res.statusCode).toBe(code); + return res.body; +} + +/** + * Checks whether the given supertes result has both the given status code and + * body data (using jest). This method will cause the surrounding jest test to + * fail if either does not match. + * @template T The type of the body (should be an object). + * @param req The result from supertest. + * @param data A Response object holding the expected values. + */ +export async function expectResponse( + req: supertest.Test, + data: Response +) { + const body = await expectHttp(req, data.code); + expect(body).toStrictEqual(data.data); +} + +/** + * Convenience wrapper around expectResponse for ApiError values. + * @see expectResponse(req, data). + * @param req The result from supertest. + * @param err The API error you expect the server to 'throw'. + */ +export async function expectApiError(req: supertest.Test, err: ApiError) { + return expectResponse(req, { + code: err.http, + data: { success: false, reason: err.reason }, + }); +} + +/** + * Calls the given endpoint without a session key, and expects an API error of + * type unauthenticated request. + * @template T The type of data held in the body (can be undefined). + * @param verb The HTTP verb to use. + * @param ep The endpoint to call (should start with a leading `/`). + * @param data The data to pass (both request parameters and body data). Each + * of these values is passed as a separate request. + * @param config The configuration to use. If this parameter is not given, uses + * the default config. This value is never modified, and is re-used for each \ + * object in the data parameter. + */ +export async function runNoSessionKey( + verb: Verb, + ep: string, + data: Data[], + config: Config = conf +) { + const updConf: Config = { + ...config, + auth: { enable: false, type: "", value: "" }, + }; + + await Promise.all( + data.map(async (sub) => { + const req = endpoint(verb, ep, sub, updConf); + await expectApiError(req, errors.cookUnauthenticated()); + }) + ); +} + +/** + * Calls the given endpoint with a random, invalid session key, and expects an + * API error of type unauthenticated request. + * @template T The type of data held in the body (can be undefined). + * @param verb The HTTP verb to use. + * @param ep The endpoint to call (should start with a leading `/`). + * @param data The data to pass (both request parameters and body data). Each + * of these values is passed as a separate request. + * @param config The configuration to use. If this parameter is not given, uses + * the default config. This value is never modified, and is re-used for each \ + * object in the data parameter. + */ +export async function runInvalidSessionKey< + T extends string | object | undefined +>(verb: Verb, ep: string, data: Data[], config: Config = conf) { + await Promise.all( + data.map(async (sub) => { + let key = ""; + let found = false; + do { + // generate unused key (shouldn't usually take more than one try) + key = generateKey(); + const tmp = await prisma.session_keys.findUnique({ + where: { session_key: key }, + }); + found = tmp != null; + } while (found); + + const withKey = keyConf(key, config, true); + const req = endpoint(verb, ep, sub, withKey); + await expectApiError(req, errors.cookUnauthenticated()); + }) + ); +} + +const realLog = console.log.bind(global.console); +const logStub = jest.fn(() => { + /* does nothing, NOTHING! */ +}); + +// disable console.log because it's annoying +beforeAll(() => { + global.console.log = logStub; +}); + +// re-enable console.log, just in case +afterAll(() => { + global.console.log = realLog; +}); diff --git a/backend/tests/routes_integration/login.test.ts b/backend/tests/routes_integration/login.test.ts new file mode 100644 index 00000000..d1d4a382 --- /dev/null +++ b/backend/tests/routes_integration/login.test.ts @@ -0,0 +1,185 @@ +import * as helpers from "./integr"; +import { errors } from "../../utility"; +import * as db from "../database_setup"; +import prisma from "../../prisma/prisma"; +import "../integration_setup"; +import { ApiError, StringDict } from "../../types"; +import * as config from "../../config.json"; +import * as bcrypt from "bcrypt"; +import { account_status_enum } from "@prisma/client"; + +let ogPasswords: db.OGNamePass[] = []; + +const credError: ApiError = { + http: 409, + reason: "Invalid e-mail or password.", +}; +const disabledError: ApiError = { + http: 409, + reason: "Account is disabled.", +}; + +describe("POST /login endpoint", () => { + const loginConfig = { + ...helpers.conf, + auth: { enable: false, type: "", value: "" }, + }; + + test(" -> with missing arguments", async () => { + const bodies = [{}, { name: "jeff" }, { pass: "jeff" }]; + await Promise.all( + bodies.map(async (v) => { + const request = helpers.endpoint( + "post", + "/login", + { body: v }, + loginConfig + ); + await helpers.expectApiError( + request, + errors.cookArgumentError() + ); + }) + ); + }); + + test(" -> with invalid email addresses", async () => { + await Promise.all( + ogPasswords.map(async (og) => { + const bd = { ...og, name: "some" + og.name }; // modify email addresses + const req = helpers.endpoint( + "post", + "/login", + { body: bd }, + loginConfig + ); + return helpers.expectApiError(req, credError); + }) + ); + }); + + test(" -> with invalid passwords", async () => { + await Promise.all( + ogPasswords.map(async (og) => { + const bd = { ...og, pass: "some" + og.pass }; // modify passwords + const req = helpers.endpoint( + "post", + "/login", + { body: bd }, + loginConfig + ); + return helpers.expectApiError(req, credError); + }) + ); + }); + + test(" -> with valid credentials", async () => { + const keys = await Promise.all( + ogPasswords.map(async (og) => { + const req = helpers.endpoint( + "post", + "/login", + { body: og }, + loginConfig + ); + return helpers.expectHttp(req, 200).then((x) => ({ + key: x.sessionkey as string, + name: og.name, + })); + }) + ); + + expect(new Set(keys.map((x) => x.key)).size).toBe(keys.length); // all keys are unique + + await Promise.all( + keys.map(async (v) => { + const res = await prisma.session_keys.findUnique({ + where: { + session_key: v.key, + }, + select: { + login_user: { select: { person: true } }, + }, + }); + + expect(res).not.toBeNull(); // existence + expect(res?.login_user.person.email).toBe(v.name); // match email + }) + ); + }); + + test(" -> with disabled account", async () => { + // set up disabled account + const pass = "imapassword"; + const hash = await bcrypt.hash( + pass, + config.encryption.encryptionRounds + ); + const user = { + password: hash, + is_admin: false, + is_coach: false, + account_status: "DISABLED" as account_status_enum, + }; + const person = { + email: "person@person.com", + name: "person", + }; + await prisma.person.create({ data: person }).then((p) => { + const u = { ...user, person_id: p.person_id }; + return prisma.login_user.create({ data: u }); + }); + + // call ep + const req = helpers.endpoint( + "post", + "/login", + { body: { name: person.email, pass: pass } }, + loginConfig + ); + await helpers.expectApiError(req, disabledError); + }); +}); + +describe("DELETE /login endpoint", () => { + test(" -> with missing session key", async () => { + await helpers.runNoSessionKey("delete", "/login", [{}]); + }); + + test(" -> with invalid session key", async () => { + await helpers.runInvalidSessionKey("delete", "/login", [{}]); + }); + + test(" -> with valid session key", async () => { + // setup + const resp = { code: 200, data: { success: true } }; + const byUser: StringDict<{ keys: string[]; user: number }> = {}; + (await prisma.session_keys.findMany()).forEach((key) => { + if (key.login_user_id in byUser) + byUser[key.login_user_id.toString()].keys.push(key.session_key); + else + byUser[key.login_user_id.toString()] = { + keys: [key.session_key], + user: key.login_user_id, + }; + }); + + for (const user in byUser) { + expect(byUser[user].keys.length).toBeGreaterThan(0); // quite important + const conf = helpers.keyConf( + byUser[user].keys[0], + helpers.conf, + true + ); + const req = helpers.endpoint("delete", "/login", {}, conf); + await helpers.expectResponse(req, resp); // ep succeeds + + const result = await prisma.session_keys.findMany({ + where: { login_user_id: byUser[user].user }, + }); + expect(result.length).toBe(0); // no keys left for user + } + }); +}); + +beforeAll(async () => (ogPasswords = await db.hashAllPasswords())); diff --git a/backend/tests/routes_unit/admin.test.ts b/backend/tests/routes_unit/admin.test.ts index f088fc56..e334a9b5 100644 --- a/backend/tests/routes_unit/admin.test.ts +++ b/backend/tests/routes_unit/admin.test.ts @@ -27,14 +27,18 @@ import * as ormP from "../../orm_functions/person"; jest.mock("../../orm_functions/person"); const ormPMock = ormP as jest.Mocked; +import * as ormSe from "../../orm_functions/session_key"; +jest.mock("../../orm_functions/session_key"); +const ormSeMock = ormSe as jest.Mocked; + import * as admin from "../../routes/admin"; +import { errors } from "../../utility"; const people: (login_user & { person: person })[] = [ { person: { person_id: 1, - firstname: "Jeffrey", - lastname: "Jan", + name: "Jeffrey Jan", email: "jeffrey@jan.be", github: null, github_id: null, @@ -49,8 +53,7 @@ const people: (login_user & { person: person })[] = [ { person: { person_id: 2, - firstname: "Jan", - lastname: "Jeffrey", + name: "Jan Jeffrey", email: null, github: "@jan_jeffrey", github_id: "9846516845", @@ -111,6 +114,10 @@ beforeEach(() => { if (v != 1 && v != 2) return Promise.reject(); return Promise.resolve(v == 1 ? people[0] : people[1]); }); + ormLMock.deleteLoginUserFromDB.mockImplementation((id) => { + if (id !== 1 && id !== 2) return Promise.reject(); + return Promise.resolve(); + }); ormPMock.deletePersonById.mockImplementation((v) => { if (v != 1 && v != 2) return Promise.reject(); return Promise.resolve(v == 1 ? people[0].person : people[1].person); @@ -126,8 +133,7 @@ beforeEach(() => { person_id: 1, email: "test@email.com", github: null, - firstname: "test", - lastname: "test", + name: "test", github_id: null, }, }); @@ -146,6 +152,7 @@ afterEach(() => { ormLMock.searchAllAdminLoginUsers.mockReset(); ormLMock.deleteLoginUserByPersonId.mockReset(); + ormLMock.deleteLoginUserFromDB.mockReset(); ormLMock.updateLoginUser.mockReset(); ormPMock.deletePersonById.mockReset(); }); @@ -165,7 +172,7 @@ test("Can list all admins.", async () => { const res = people.map((val) => ({ person_data: { id: val.person.person_id, - name: val.person.firstname + " " + val.person.lastname, + name: val.person.name, email: val.person.email, github: val.person.github, }, @@ -200,6 +207,69 @@ test("Can modify a single admin (1).", async () => { expect(utilMock.mutable).toHaveBeenCalledTimes(1); }); +test("Can't modify yourself as an admin", async () => { + const req = getMockReq(); + req.body = { id: 0, sessionkey: "abcd" }; + await expect(admin.modAdmin(req)).rejects.toBe(errors.cookInvalidID()); +}); + +test("Can modify a single admin and update the login user twice", async () => { + const req = getMockReq(); + req.body = { + id: 7, + sessionkey: "abcd", + isAdmin: false, + isCoach: false, + accountStatus: "PENDING", + }; + const res = { id: 7, name: "Jeffrey Jan" }; + + ormLMock.updateLoginUser.mockImplementationOnce(() => + Promise.resolve({ + person: { + person_id: 1, + name: "Jeffrey Jan", + email: "jeffrey@jan.be", + github: null, + github_id: null, + }, + is_coach: false, + is_admin: false, + login_user_id: 7, + person_id: 1, + password: "jeffreyForEver", + account_status: "PENDING", + }) + ); + + ormLMock.updateLoginUser.mockImplementationOnce(() => + Promise.resolve({ + person: { + person_id: 1, + name: "Jeffrey Jan", + email: "jeffrey@jan.be", + github: null, + github_id: null, + }, + is_coach: false, + is_admin: false, + login_user_id: 7, + person_id: 1, + password: "jeffreyForEver", + account_status: "DISABLED", + }) + ); + + ormSeMock.removeAllKeysForLoginUserId.mockResolvedValue( + Promise.resolve({ count: 1 }) + ); + + await expect(admin.modAdmin(req)).resolves.toStrictEqual(res); + + ormLMock.updateLoginUser.mockReset(); + ormSeMock.removeAllKeysForLoginUserId.mockReset(); +}); + test("Can modify a single admin (2).", async () => { const req = getMockReq(); req.body = { @@ -230,7 +300,22 @@ test("Can delete admins", async () => { await expect(admin.deleteAdmin(req)).resolves.toStrictEqual(res); expectCall(utilMock.isAdmin, req.body); expectCall(reqMock.parseDeleteAdminRequest, req); - expectCall(ormLMock.deleteLoginUserByPersonId, req.body.id); - expectCall(ormPMock.deletePersonById, req.body.id); + expectCall(ormLMock.deleteLoginUserFromDB, req.body.id); expect(utilMock.mutable).toHaveBeenCalledTimes(1); }); + +test("Can't delete yourself as an admin", async () => { + const req = getMockReq(); + req.body = { sessionkey: "abcd" }; + const id = 0; + req.params.id = id.toString(); + + reqMock.parseDeleteAdminRequest.mockResolvedValue({ + sessionkey: "abcd", + id: 0, + }); + + await expect(admin.deleteAdmin(req)).rejects.toBe(errors.cookInvalidID()); + + reqMock.parseDeleteAdminRequest.mockReset(); +}); diff --git a/backend/tests/routes_unit/coach.test.ts b/backend/tests/routes_unit/coach.test.ts index 897804af..80888d67 100644 --- a/backend/tests/routes_unit/coach.test.ts +++ b/backend/tests/routes_unit/coach.test.ts @@ -26,6 +26,9 @@ const ormLMock = ormL as jest.Mocked; import * as ormP from "../../orm_functions/person"; jest.mock("../../orm_functions/person"); const ormPMock = ormP as jest.Mocked; +import * as ormS from "../../orm_functions/session_key"; +jest.mock("../../orm_functions/session_key"); +const ormSMock = ormS as jest.Mocked; import * as coach from "../../routes/coach"; @@ -33,8 +36,7 @@ const people: (login_user & { person: person })[] = [ { person: { person_id: 1, - firstname: "Jeffrey", - lastname: "Jan", + name: "Jeffrey Jan", email: "jeffrey@jan.be", github: null, github_id: null, @@ -49,8 +51,7 @@ const people: (login_user & { person: person })[] = [ { person: { person_id: 2, - firstname: "Jan", - lastname: "Jeffrey", + name: "Jan Jeffrey", email: null, github: "@jan_jeffrey", github_id: "16968456845", @@ -97,12 +98,16 @@ beforeEach(() => { person_id: 1, email: "test@email.com", github: null, - firstname: "test", - lastname: "test", + name: "test", github_id: null, }, }); + ormLMock.deleteLoginUserFromDB.mockImplementation((id) => { + if (id !== 1 && id !== 2) return Promise.reject(); + return Promise.resolve(); + }); + // mocks for utility utilMock.checkSessionKey.mockImplementation((v) => Promise.resolve({ @@ -129,7 +134,12 @@ beforeEach(() => { ormLMock.searchAllCoachLoginUsers.mockResolvedValue(people); ormLMock.updateLoginUser.mockImplementation((v) => { if (v.loginUserId != 7 && v.loginUserId != 8) return Promise.reject({}); - return Promise.resolve(v.loginUserId == 7 ? people[0] : people[1]); + const res = v.loginUserId == 7 ? people[0] : people[1]; + if (v.isAdmin == false && v.isCoach == false) { + res.is_admin = false; + res.is_coach = false; + } + return Promise.resolve(res); }); ormLMock.deleteLoginUserByPersonId.mockImplementation((v) => { if (v != 1 && v != 2) { @@ -146,6 +156,8 @@ beforeEach(() => { } return Promise.resolve(v == 1 ? people[0].person : people[1].person); }); + + ormSMock.removeAllKeysForLoginUserId.mockResolvedValue({ count: 0 }); }); // reset @@ -164,8 +176,12 @@ afterEach(() => { ormLMock.getAllLoginUsers.mockReset(); ormLMock.searchAllCoachLoginUsers.mockReset(); ormLMock.deleteLoginUserByPersonId.mockReset(); + ormLMock.deleteLoginUserFromDB.mockReset(); + ormLMock.updateLoginUser.mockReset(); ormPMock.deletePersonById.mockReset(); + + ormSMock.removeAllKeysForLoginUserId.mockReset(); }); function expectCall(func: T, val: U) { @@ -178,13 +194,14 @@ test("Can list all coaches", async () => { const res = people.map((val) => ({ person_data: { id: val.person.person_id, - name: val.person.firstname, + name: val.person.name, email: val.person.email, github: val.person.github, }, coach: val.is_coach, admin: val.is_admin, activated: val.account_status as string, + login_user_id: val.login_user_id, })); await expect(coach.listCoaches(req)).resolves.toStrictEqual({ @@ -235,16 +252,102 @@ test("Can modify a single coach (2).", async () => { expect(utilMock.mutable).toHaveBeenCalledTimes(1); }); +test("Can force-logout a coach", async () => { + const req = getMockReq(); + req.body = { + id: 7, + isAdmin: false, + isCoach: false, + sessionkey: "abcd", + }; + const res = { id: 7, name: "Jeffrey Jan" }; + await expect(coach.modCoach(req)).resolves.toStrictEqual(res); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(0); + expectCall(reqMock.parseUpdateCoachRequest, req); + expect(ormLMock.updateLoginUser).toHaveBeenCalledTimes(2); + expect(utilMock.isAdmin).toHaveBeenCalledTimes(1); + expect(utilMock.mutable).toHaveBeenCalledTimes(1); + expectCall(ormSMock.removeAllKeysForLoginUserId, 7); +}); + test("Can delete coaches", async () => { const req = getMockReq(); req.body = { id: 1, sessionkey: "abcd" }; const res = {}; - console.log(req.body); await expect(coach.deleteCoach(req)).resolves.toStrictEqual(res); expectCall(utilMock.isAdmin, req.body); expectCall(reqMock.parseDeleteCoachRequest, req); - expectCall(ormLMock.deleteLoginUserByPersonId, req.body.id); - expectCall(ormPMock.deletePersonById, req.body.id); + expectCall(ormLMock.deleteLoginUserFromDB, req.body.id); expect(utilMock.mutable).toHaveBeenCalledTimes(1); }); + +test("Can't update oneself", async () => { + utilMock.isAdmin.mockReset(); + utilMock.isAdmin.mockImplementation((v) => + Promise.resolve({ + userId: 7, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }) + ); + + const req = getMockReq(); + req.body = { + id: 7, + isAdmin: false, + isCoach: false, + sessionkey: "abcd", + }; + + await expect(coach.modCoach(req)).rejects.toStrictEqual( + util.errors.cookInvalidID() + ); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(0); + expectCall(reqMock.parseUpdateCoachRequest, req); + expect(ormLMock.updateLoginUser).toHaveBeenCalledTimes(0); + expect(utilMock.isAdmin).toHaveBeenCalledTimes(1); + expect(utilMock.mutable).toHaveBeenCalledTimes(1); +}); + +test("Can assign coach role when activating", async () => { + const req = getMockReq(); + req.body = { + id: 7, + isAdmin: false, + isCoach: false, + accountStatus: account_status_enum.ACTIVATED, + sessionkey: "abcd", + }; + ormLMock.getLoginUserById.mockResolvedValue({ + login_user_id: 1, + person_id: 1, + password: "test", + is_admin: false, + is_coach: false, + account_status: account_status_enum.DISABLED, + person: { + person_id: 1, + email: "test@email.com", + github: null, + name: "test", + github_id: null, + }, + }); + const res = { id: 7, name: "Jeffrey Jan" }; + await expect(coach.modCoach(req)).resolves.toStrictEqual(res); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(0); + expectCall(reqMock.parseUpdateCoachRequest, req); + expectCall(ormLMock.updateLoginUser, { + loginUserId: 7, + isAdmin: false, + isCoach: true, + accountStatus: account_status_enum.ACTIVATED, + }); + expect(utilMock.isAdmin).toHaveBeenCalledTimes(1); + expect(utilMock.mutable).toHaveBeenCalledTimes(1); + + ormLMock.getLoginUserById.mockReset(); +}); diff --git a/backend/tests/routes_unit/followup.test.ts b/backend/tests/routes_unit/followup.test.ts index 40951ed1..a2c1c19f 100644 --- a/backend/tests/routes_unit/followup.test.ts +++ b/backend/tests/routes_unit/followup.test.ts @@ -29,7 +29,8 @@ jest.mock("../../utility", () => { ...og, checkSessionKey: jest.fn(), isAdmin: jest.fn(), - }; // we want to only mock checkSessionKey and isAdmin + checkYearPermissionStudent: jest.fn(), + }; // we want to only mock checkSessionKey, isAdmin and checkYearPermissionStudent }); export const utilMock = util as jest.Mocked; @@ -42,7 +43,12 @@ import * as osoc_ from "../../orm_functions/osoc"; jest.mock("../../orm_functions/osoc"); const osocMock = osoc_ as jest.Mocked; +import * as login_user_orm from "../../orm_functions/login_user"; +jest.mock("../../orm_functions/login_user"); +const ormlMock = login_user_orm as jest.Mocked; + import * as followup from "../../routes/followup"; +import { errors } from "../../utility"; function expectCall(func: T, val: U) { expect(func).toHaveBeenCalledTimes(1); @@ -62,6 +68,7 @@ type _appl = job_application & { attachment: attachment[]; job_application_skill: job_application_skill[]; applied_role: applied_role[]; + osoc: osoc; }; const jobapps: _appl[] = [ @@ -78,7 +85,7 @@ const jobapps: _appl[] = [ edu_level: "noob", edu_year: "pro", edu_institute: "someones basement", - email_status: "SCHEDULED", + email_status: "AWAITING_PROJECT", created_at: new Date(Date.now()), job_application_skill: [ { @@ -97,6 +104,10 @@ const jobapps: _appl[] = [ applied_role: [ { applied_role_id: 2, job_application_id: 0, role_id: 6 }, ], + osoc: { + osoc_id: 0, + year: 2022, + }, }, { job_application_id: 2, @@ -111,7 +122,7 @@ const jobapps: _appl[] = [ edu_level: "noob", edu_year: "pro", edu_institute: "someones basement", - email_status: "SCHEDULED", + email_status: "APPLIED", created_at: new Date(Date.now()), job_application_skill: [ { @@ -130,6 +141,10 @@ const jobapps: _appl[] = [ applied_role: [ { applied_role_id: 2, job_application_id: 2, role_id: 6 }, ], + osoc: { + osoc_id: 0, + year: 2022, + }, }, ]; @@ -161,9 +176,14 @@ beforeEach(() => { is_coach: true, }) ); + utilMock.checkYearPermissionStudent.mockImplementation((v) => + Promise.resolve(v) + ); osocMock.getLatestOsoc.mockResolvedValue(osocdat); + osocMock.getOsocById.mockResolvedValue(osocdat); jappMock.getJobApplicationByYear.mockResolvedValue(jobapps); + jappMock.getJobApplication.mockResolvedValue(jobapps[0]); jappMock.getLatestJobApplicationOfStudent.mockImplementation((v) => v == 5 ? Promise.resolve(jobapps[0]) @@ -178,6 +198,8 @@ beforeEach(() => { ? Promise.resolve({ ...jobapps[1], email_status: u }) : Promise.reject() ); + + ormlMock.getOsocYearsForLoginUser.mockResolvedValue([2022]); }); afterEach(() => { @@ -187,28 +209,16 @@ afterEach(() => { utilMock.checkSessionKey.mockReset(); utilMock.isAdmin.mockReset(); + utilMock.checkYearPermissionStudent.mockReset(); osocMock.getLatestOsoc.mockReset(); + osocMock.getOsocById.mockReset(); jappMock.getJobApplicationByYear.mockReset(); + jappMock.getJobApplication.mockReset(); jappMock.getLatestJobApplicationOfStudent.mockReset(); jappMock.changeEmailStatusOfJobApplication.mockReset(); -}); -test("Can get all followup data", async () => { - const req: express.Request = getMockReq(); - - await expect(followup.listFollowups(req)).resolves.toStrictEqual({ - data: jobapps.map((x) => ({ - student: x.student_id, - application: x.job_application_id, - status: x.email_status, - })), - }); - expectCall(utilMock.checkSessionKey, { sessionkey: "abcd" }); - expectCall(reqMock.parseFollowupAllRequest, req); - expect(osocMock.getLatestOsoc).toHaveBeenCalledTimes(1); - expectCall(jappMock.getJobApplicationByYear, osocdat.year); - expectNoCall(utilMock.isAdmin); + ormlMock.getOsocYearsForLoginUser.mockReset(); }); test("Can get single followup", async () => { @@ -220,7 +230,22 @@ test("Can get single followup", async () => { }); expectCall(utilMock.checkSessionKey, { sessionkey: "abcd", id: 5 }); expectCall(reqMock.parseGetFollowupStudentRequest, req); - expectCall(jappMock.getLatestJobApplicationOfStudent, 5); + expect(jappMock.getJobApplication).toHaveBeenCalledTimes(1); + expectNoCall(utilMock.isAdmin); +}); + +test("Cannot get single followup because invalid year permissions", async () => { + const req: express.Request = getMockReq(); + // set the visible years NOT to 2022 + ormlMock.getOsocYearsForLoginUser.mockReset(); + ormlMock.getOsocYearsForLoginUser.mockResolvedValue([2000, 2001]); + + await expect(followup.getFollowup(req)).rejects.toBe( + errors.cookInsufficientRights() + ); + expectCall(utilMock.checkSessionKey, { sessionkey: "abcd", id: 5 }); + expectCall(reqMock.parseGetFollowupStudentRequest, req); + expect(jappMock.getJobApplication).toHaveBeenCalledTimes(1); expectNoCall(utilMock.isAdmin); }); diff --git a/backend/tests/routes_unit/form.test.ts b/backend/tests/routes_unit/form.test.ts deleted file mode 100644 index 776d2aa7..00000000 --- a/backend/tests/routes_unit/form.test.ts +++ /dev/null @@ -1,697 +0,0 @@ -import { getMockReq } from "@jest-mock/express"; - -import * as form_router from "../../routes/form"; - -import * as T from "../../types"; -import express from "express"; -import * as Rq from "../../request"; -import { errors } from "../../utility"; -/*import express from "express"; -import * as Rq from "../../request"; -import { errors } from "../../utility";*/ -// setup mock for form -//jest.mock("../../routes/form"); -//const formMock = form as jest.Mocked; -import * as fs from "fs"; -import * as path from "path"; - -const keys = [ - "question_mK177D", - "question_wLpAAJ", - "question_npOjjP", - "question_31VZZb", - "question_wMRkk8", - "question_mJzaaX", - "question_wgGyyJ", - "question_3yYKKd", - "question_3X0VVz", - "question_w8xvvr", - "question_n0O22A", - "question_wzYppg", - "question_w5x66Q", - "question_wddLLV", - "question_mYaEEv", - "question_mDzrrE", - "question_3lrooX", - "question_mRPXXQ", - "question_woGrrN", - "question_nGlNNO", - "question_mOGppM", - "question_mVJRR6", - "question_nPOMMx", - "question_3EWjj2", - "question_nrPNNX", - "question_w4rWW5", - "question_3jPdd1", - "question_w2PqqM", - "question_3xYkkk", - "question_mZ6555", - "question_3NW55p", - "question_3qAZZ5", - "question_wQ5221", - "question_n9DGGX", - "question_meeZZQ", - "question_nW599R", - "question_waYNN2", -]; - -function readDataTestForms(): T.Requests.Form[] { - return Object.values( - fs.readdirSync(path.join(__dirname, "/../../../testforms")) - ) - .filter((filename) => filename.includes("testform")) - .map((filename) => { - const readFile = (path: string) => fs.readFileSync(path, "utf8"); - const fileData = readFile( - path.join(__dirname, `/../../../testforms/${filename}`) - ); - return JSON.parse(fileData); - }); -} - -const form_obj: T.Requests.Form = { - createdAt: "2022-04-24T10:41:30.976Z", - data: { - fields: [ - { - key: "question_mK177D", - value: "343f74a1-7b3d-481e-94f1-cfd613d78f00", - options: [ - { - id: "343f74a1-7b3d-481e-94f1-cfd613d78f00", - text: "Yes", - }, - { - id: "2cf437cc-fee4-496b-8e46-f6c037dca583", - text: "No", - }, - ], - }, - { - key: "question_wLpAAJ", - value: "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", - options: [ - { - id: "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", - text: "Yes, I can work with a student employment agreement in Belgium", - }, - { - id: "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", - text: "Yes, I can work as a volunteer in Belgium", - }, - { - id: "230a7690-7e05-43d5-97a4-58c0e37142dc", - text: "No – but I would like to join this experience for free", - }, - { - id: "9a065686-5d60-423f-a343-db8ae9066028", - text: "No, I won’t be able to work as a student, as a volunteer or for free.", - }, - ], - }, - { - key: "question_npOjjP", - value: "115ad290-a86e-42f5-939e-8276ff41e749", - options: [ - { - id: "115ad290-a86e-42f5-939e-8276ff41e749", - text: "Yes", - }, - { - id: "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", - text: "No, I wouldn't be able to work for the majority of days.", - }, - ], - }, - { - key: "question_31VZZb", - value: "Test responsibility", - }, - { - key: "question_wMRkk8", - value: "Bob", - }, - { - key: "question_mJzaaX", - value: "Dylan", - }, - { - key: "question_wgGyyJ", - value: "35e07206-f052-4826-8965-515ed783a43e", - options: [ - { - id: "35e07206-f052-4826-8965-515ed783a43e", - text: "Yes", - }, - { - id: "e3558697-3a38-4137-b699-1fb8ec93e9ab", - text: "No", - }, - ], - }, - { - key: "question_3yYKKd", - value: "Bobby", - }, - { - key: "question_3X0VVz", - value: "2bcf2809-3efe-407d-87c1-dabcf3db0743", - options: [ - { - id: "d664cd5f-121f-421c-8f2c-e1b8b6505899", - text: "Female", - }, - { - id: "2bcf2809-3efe-407d-87c1-dabcf3db0743", - text: "Male", - }, - { - id: "afd31775-f165-41d0-9dd2-45dd4ae1c90a", - text: "Transgender", - }, - { - id: "fc2cc0be-6688-4ab8-9567-36bedbe829b2", - text: "Rather not say", - }, - ], - }, - { - key: "question_w8xvvr", - value: "8b2065a1-09f1-46dc-a03e-138a20160230", - options: [ - { - id: "8b2065a1-09f1-46dc-a03e-138a20160230", - text: "Yes", - }, - { - id: "e08c0951-9ea4-4781-b5e4-a5252b91855f", - text: "No", - }, - ], - }, - { - key: "question_n0O22A", - value: "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", - options: [ - { - id: "97e74546-7f92-422c-b2be-ffaf7ef3f50b", - text: "she/her/hers", - }, - { - id: "a8a3c71b-2d52-4319-9399-e13eeffb7e99", - text: "he/him/his", - }, - { - id: "57489d99-aa62-4f9a-a9b9-5975570ea7d7", - text: "they/them/theirs", - }, - { - id: "071f603c-e1f6-4212-bc2d-57a173a076b6", - text: "ze/hir/hir ", - }, - { - id: "4e0d7394-23b3-4469-ad2d-2b6482186f8c", - text: "by firstname", - }, - { - id: "a5c6726f-661e-43e1-b913-c33683f20ddd", - text: "by call name", - }, - { - id: "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", - text: "other", - }, - ], - }, - { - key: "question_wzYppg", - value: "he/him/his", - }, - { - key: "question_w5x66Q", - value: "86bb74b6-5dd8-4ce0-b28a-962604d2c630", - options: [ - { - id: "66165a2c-404a-4def-b925-846769a123bd", - text: "Dutch", - }, - { - id: "86bb74b6-5dd8-4ce0-b28a-962604d2c630", - text: "English", - }, - { - id: "551bd941-9c3c-4805-89c0-22ae46ac89d0", - text: "French", - }, - { - id: "1ed59443-b164-4ddf-85ff-c603cd4edaf1", - text: "German", - }, - { - id: "3594c098-46fd-4bf9-98b3-c11e568c3403", - text: "Other", - }, - ], - }, - { - key: "question_wddLLV", - value: null, - }, - { - key: "question_mYaEEv", - value: "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", - options: [ - { - id: "18419bd9-82b4-40f8-980a-10ce9a022db3", - text: "★ I can understand your form, but it is hard for me to reply.", - }, - { - id: "eeba838b-5a34-4c92-a8ca-4cab70d19f93", - text: "★★ I can have simple conversations.", - }, - { - id: "6023fc5b-6ae2-4280-a691-37dc781044d8", - text: "★★★ I can express myself, understand people and get a point across.", - }, - { - id: "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", - text: "★★★★ I can have extensive and complicated conversations.", - }, - { - id: "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", - text: "★★★★★ I am fluent.", - }, - ], - }, - { - key: "question_mDzrrE", - value: "0487294163", - }, - { - key: "question_3lrooX", - value: "bob.dylan@gmail.com", - }, - { - key: "question_mRPXXQ", - value: [ - { - url: "https://storage.googleapis.com/tally-response-assets/repXzN/ee3f362a-f4ab-4e19-9fe4-3886aff77462/attachment.txt", - }, - ], - }, - { - key: "question_woGrrN", - value: null, - }, - { - key: "question_nGlNNO", - value: [ - { - url: "https://storage.googleapis.com/tally-response-assets/repXzN/4b6f238f-cd08-4dfe-be66-9dde191ecb09/attachment.txt", - }, - ], - }, - { - key: "question_mOGppM", - value: null, - }, - { - key: "question_mVJRR6", - value: [ - { - url: "https://storage.googleapis.com/tally-response-assets/repXzN/d3dda569-58db-45e0-a1dc-423ac1d6432e/attachment.txt", - }, - ], - }, - { - key: "question_nPOMMx", - value: null, - }, - { - key: "question_3EWjj2", - value: "I am very motivated", - }, - { - key: "question_nrPNNX", - value: "I am funny", - }, - { - key: "question_w4rWW5", - value: [ - "63669061-f3e1-4b97-addc-f8b37a3989f4", - "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", - ], - options: [ - { - id: "63669061-f3e1-4b97-addc-f8b37a3989f4", - text: "Backend development", - }, - { - id: "816606cb-4f87-4632-9c27-7f09e1c0d0f4", - text: "Business management", - }, - { - id: "dfedd70f-5780-42b4-bc74-85d3c4e69225", - text: "Communication Sciences", - }, - { - id: "de2a0d9b-2cc1-472f-ad76-954677a8afb1", - text: "Computer Sciences", - }, - { - id: "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", - text: "Design", - }, - { - id: "ef021761-9972-46d6-960a-0236ba723963", - text: "Frontend development", - }, - { - id: "bdefa065-f120-488b-bd01-244c5a59f20e", - text: "Marketing", - }, - { - id: "c2c15641-dee6-4712-8fdf-0448d2dcaed1", - text: "Photography", - }, - { - id: "e9964b65-12b7-4179-91bc-d63f5f02aee9", - text: "Videography", - }, - { - id: "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", - text: "Other", - }, - ], - }, - { - key: "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", - value: true, - }, - { - key: "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", - value: false, - }, - { - key: "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", - value: false, - }, - { - key: "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", - value: false, - }, - { - key: "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", - value: false, - }, - { - key: "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", - value: false, - }, - { - key: "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", - value: false, - }, - { - key: "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", - value: false, - }, - { - key: "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", - value: false, - }, - { - key: "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", - value: true, - }, - { - key: "question_3jPdd1", - value: "Database design", - }, - { - key: "question_w2PqqM", - value: ["a27ad504-f524-4e5b-9919-2ad70c14814a"], - options: [ - { - id: "ee039478-24af-46f0-8619-d0615512c2b7", - text: "A professional Bachelor", - }, - { - id: "a27ad504-f524-4e5b-9919-2ad70c14814a", - text: "An academic Bachelor", - }, - { - id: "97dbef1b-d707-4585-b61b-45c99db6c54c", - text: "An associate degree", - }, - { - id: "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", - text: "A master's degree", - }, - { - id: "25c435fd-f20a-4e70-bafd-0563089e28ec", - text: "Doctoral degree", - }, - { - id: "e5f9b310-6087-4c44-8422-ccee50b9378b", - text: "No diploma, I am self taught", - }, - { - id: "67e44797-6696-4605-b1bd-bf76859c70f9", - text: "Other", - }, - ], - }, - { - key: "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", - value: false, - }, - { - key: "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", - value: true, - }, - { - key: "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", - value: false, - }, - { - key: "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", - value: false, - }, - { - key: "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", - value: false, - }, - { - key: "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", - value: false, - }, - { - key: "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", - value: false, - }, - { - key: "question_3xYkkk", - value: "No diploma", - }, - { - key: "question_mZ6555", - value: 5, - }, - { - key: "question_3NW55p", - value: "Third bachelor", - }, - { - key: "question_3qAZZ5", - value: "Ghent university", - }, - { - key: "question_wQ5221", - value: [ - "687908c0-7091-429c-9f99-cf9670503892", - "dede10c8-a949-463c-8ae8-73f6fab6a362", - ], - options: [ - { - id: "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", - text: "Front-end developer", - }, - { - id: "687908c0-7091-429c-9f99-cf9670503892", - text: "Back-end developer", - }, - { - id: "def165c9-d40a-4d13-b174-98d480e1dd41", - text: "UX / UI designer", - }, - { - id: "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", - text: "Graphic designer", - }, - { - id: "37c7da5d-361c-4000-b8ed-fcf8e69971f0", - text: "Business Modeller", - }, - { - id: "07228f94-e28d-41f6-ac6e-ccd039921f58", - text: "Storyteller", - }, - { - id: "4b1c6ba6-e945-465e-9222-de02d44988ce", - text: "Marketer", - }, - { - id: "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", - text: "Copywriter", - }, - { - id: "e7f54c05-e90b-4967-b9a5-7fa997abdabc", - text: "Video editor", - }, - { - id: "7418ba9a-e88b-4a4c-98e7-4f346d61024e", - text: "Photographer", - }, - { - id: "dede10c8-a949-463c-8ae8-73f6fab6a362", - text: "Other", - }, - ], - }, - { - key: "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", - value: false, - }, - { - key: "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", - value: true, - }, - { - key: "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", - value: false, - }, - { - key: "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", - value: false, - }, - { - key: "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", - value: false, - }, - { - key: "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", - value: false, - }, - { - key: "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", - value: false, - }, - { - key: "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", - value: false, - }, - { - key: "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", - value: false, - }, - { - key: "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", - value: false, - }, - { - key: "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", - value: true, - }, - { - key: "question_n9DGGX", - value: "Database designer", - }, - { - key: "question_meeZZQ", - value: "Writing songs", - }, - { - key: "question_nW599R", - value: "127d3ef2-2929-4895-ba52-4d10bcaa1e19", - options: [ - { - id: "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", - text: "No, it's my first time participating in osoc", - }, - { - id: "127d3ef2-2929-4895-ba52-4d10bcaa1e19", - text: "Yes, I have been part of osoc before", - }, - ], - }, - { - key: "question_waYNN2", - value: "6959f608-436d-4da8-a14e-f9cedb99f705", - options: [ - { - id: "ffa7874f-52db-4058-93a1-8a015376f256", - text: "No, I don't want to be a student coach", - }, - { - id: "6959f608-436d-4da8-a14e-f9cedb99f705", - text: "Yes, I'd like to be a student coach", - }, - ], - }, - ], - }, -}; - -test("Can parse form request", () => { - const resultList: Promise[] = []; - const req: express.Request = getMockReq(); - - req.body = {}; - resultList.push( - expect(Rq.parseFormRequest(req)).rejects.toBe( - errors.cookArgumentError() - ) - ); - - const req2: express.Request = getMockReq(); - req2.body = { data: {} }; - resultList.push( - expect(Rq.parseFormRequest(req2)).rejects.toBe( - errors.cookArgumentError() - ) - ); - - const req3: express.Request = getMockReq(); - req3.body = { data: { fields: [{ value: "value" }] } }; - resultList.push( - expect(Rq.parseFormRequest(req3)).rejects.toBe( - errors.cookArgumentError() - ) - ); - - readDataTestForms().forEach((data) => { - const req4: express.Request = getMockReq(); - req4.body = { ...data }; - const v1 = expect(Rq.parseFormRequest(req4)).resolves.toHaveProperty( - "data", - data.data - ); - const v2 = expect(Rq.parseFormRequest(req4)).resolves.toHaveProperty( - "createdAt", - data.createdAt - ); - - resultList.push(v1); - resultList.push(v2); - }); - - return Promise.all(resultList); -}); - -describe.each(keys)("Questions present", (key) => { - it(`Question with key ${key} is present`, () => { - const res = form_router.filterQuestion(form_obj, key); - expect(res.data).not.toBe(null); - }); -}); diff --git a/backend/tests/routes_unit/form/add_attachments_to_database_files/add_attachments_to_database.test.ts b/backend/tests/routes_unit/form/add_attachments_to_database_files/add_attachments_to_database.test.ts new file mode 100644 index 00000000..47b9b87a --- /dev/null +++ b/backend/tests/routes_unit/form/add_attachments_to_database_files/add_attachments_to_database.test.ts @@ -0,0 +1,72 @@ +import { addAttachmentsToDatabase } from "../../../../routes/form"; + +import * as ormAt from "../../../../orm_functions/attachment"; +jest.mock("../../../../orm_functions/attachment"); +const ormAtMock = ormAt as jest.Mocked; + +test("Insert no attachments in the database", async () => { + await expect( + addAttachmentsToDatabase( + { + cv_links: { + data: [], + types: [], + }, + portfolio_links: { + data: [], + types: [], + }, + motivations: { + data: [], + types: [], + }, + }, + { id: 1 } + ) + ).resolves.toStrictEqual({}); +}); + +test("Insert attachments in the database", async () => { + ormAtMock.createAttachment.mockResolvedValueOnce({ + attachment_id: 1, + job_application_id: 1, + data: ["url1"], + type: ["CV_URL"], + }); + + ormAtMock.createAttachment.mockResolvedValueOnce({ + attachment_id: 2, + job_application_id: 1, + data: ["url2"], + type: ["PORTFOLIO_URL"], + }); + + ormAtMock.createAttachment.mockResolvedValueOnce({ + attachment_id: 3, + job_application_id: 1, + data: ["url3", "string1"], + type: ["MOTIVATION_URL", "MOTIVATION_STRING"], + }); + + await expect( + addAttachmentsToDatabase( + { + cv_links: { + data: ["url1"], + types: ["CV_URL"], + }, + portfolio_links: { + data: ["url2"], + types: ["PORTFOLIO_URL"], + }, + motivations: { + data: ["url3", "string1"], + types: ["MOTIVATION_URL", "MOTIVATION_STRING"], + }, + }, + { id: 1 } + ) + ).resolves.toStrictEqual({}); + + ormAtMock.createAttachment.mockReset(); +}); diff --git a/backend/tests/routes_unit/form/add_job_application_to_database_files/add_job_application_to_database.test.ts b/backend/tests/routes_unit/form/add_job_application_to_database_files/add_job_application_to_database.test.ts new file mode 100644 index 00000000..04a2d485 --- /dev/null +++ b/backend/tests/routes_unit/form/add_job_application_to_database_files/add_job_application_to_database.test.ts @@ -0,0 +1,150 @@ +import { + job_application, + attachment, + job_application_skill, + applied_role, +} from "@prisma/client"; + +import { addJobApplicationToDatabase } from "../../../../routes/form"; + +import * as ormJo from "../../../../orm_functions/job_application"; +jest.mock("../../../../orm_functions/job_application"); +const ormJoMock = ormJo as jest.Mocked; + +import * as ormApRo from "../../../../orm_functions/applied_role"; +jest.mock("../../../../orm_functions/applied_role"); +const ormApRoMock = ormApRo as jest.Mocked; + +import * as ormAtt from "../../../../orm_functions/attachment"; +jest.mock("../../../../orm_functions/attachment"); +const ormAttMock = ormAtt as jest.Mocked; + +import * as ormJoSk from "../../../../orm_functions/job_application_skill"; +jest.mock("../../../../orm_functions/job_application_skill"); +const ormJoSkMock = ormJoSk as jest.Mocked; + +const jobApplication: job_application & { + attachment: attachment[]; + job_application_skill: job_application_skill[]; + applied_role: applied_role[]; + osoc: { osoc_id: number; year: number }; +} = { + job_application_id: 1, + student_id: 1, + student_volunteer_info: "volunteer info", + responsibilities: null, + fun_fact: "I am funny", + student_coach: true, + osoc_id: 1, + edus: ["Backend development"], + edu_level: "A professional Bachelor", + edu_duration: 5, + edu_year: "3rd", + edu_institute: "Ghent university", + email_status: "APPLIED", + created_at: new Date("December 17, 2021 03:24:00"), + attachment: [], + job_application_skill: [], + applied_role: [], + osoc: { + osoc_id: 0, + year: 2022, + }, +}; + +// setup +beforeEach(() => { + // mocks for orm + ormJoMock.getLatestJobApplicationOfStudent.mockResolvedValue( + jobApplication + ); + ormApRoMock.deleteAppliedRolesByJobApplication.mockResolvedValue({ + count: 0, + }); + ormAttMock.deleteAllAttachmentsForApplication.mockResolvedValue({ + count: 0, + }); + ormJoSkMock.deleteSkillsByJobApplicationId.mockResolvedValue({ + count: 0, + }); + ormJoMock.deleteJobApplication.mockResolvedValue(jobApplication); + + ormJoMock.createJobApplication.mockResolvedValue({ + job_application_id: 1, + student_id: 1, + student_volunteer_info: "volunteer info", + responsibilities: null, + fun_fact: "I am funny", + student_coach: true, + osoc_id: 1, + edus: ["Backend development"], + edu_level: "A professional Bachelor", + edu_duration: 5, + edu_year: "3rd", + edu_institute: "Ghent university", + email_status: "APPLIED", + created_at: new Date("December 17, 2021 03:24:00"), + }); +}); + +// reset +afterEach(() => { + ormJoMock.getLatestJobApplicationOfStudent.mockReset(); + ormApRoMock.deleteAppliedRolesByJobApplication.mockReset(); + ormAttMock.deleteAllAttachmentsForApplication.mockReset(); + ormJoSkMock.deleteSkillsByJobApplicationId.mockReset(); + ormJoMock.deleteJobApplication.mockReset(); + ormJoMock.createJobApplication.mockReset(); +}); + +test("Insert a job application in the database, studentCoach not null", async () => { + await expect( + addJobApplicationToDatabase( + { + responsibilities: null, + funFact: "I am funny", + volunteerInfo: "volunteer info", + studentCoach: true, + osocId: 1, + educations: ["Backend development"], + educationLevel: "A professional Bachelor", + educationDuration: 5, + educationYear: "3rd", + educationInstitute: "Ghent university", + emailStatus: "AWAITING_PROJECT", + createdAt: "December 17, 2021 03:24:00", + }, + { + id: 1, + } + ) + ).resolves.toStrictEqual({ + id: 1, + }); +}); + +test("Insert a job application in the database, studentCoach null", async () => { + await expect( + addJobApplicationToDatabase( + { + responsibilities: null, + funFact: "I am funny", + volunteerInfo: "volunteer info", + studentCoach: null, + osocId: 1, + educations: ["Backend development"], + educationLevel: "A professional Bachelor", + educationDuration: 5, + educationYear: "3rd", + educationInstitute: "Ghent university", + emailStatus: "APPLIED", + createdAt: "December 17, 2021 03:24:00", + }, + { + id: 1, + } + ) + ).resolves.toStrictEqual({ + id: 1, + }); +}); diff --git a/backend/tests/routes_unit/form/add_person_to_database_files/add_person_to_database.test.ts b/backend/tests/routes_unit/form/add_person_to_database_files/add_person_to_database.test.ts new file mode 100644 index 00000000..d0e4dbe1 --- /dev/null +++ b/backend/tests/routes_unit/form/add_person_to_database_files/add_person_to_database.test.ts @@ -0,0 +1,94 @@ +import { person } from "@prisma/client"; + +import { addPersonToDatabase } from "../../../../routes/form"; + +import * as ormP from "../../../../orm_functions/person"; +jest.mock("../../../../orm_functions/person"); +const ormPMock = ormP as jest.Mocked; + +const people: person[] = [ + { + person_id: 1, + name: "Test1", + email: "test1@mail.com", + github: null, + github_id: null, + }, + { + person_id: 2, + name: "Test2", + email: "test2@mail.com", + github: null, + github_id: null, + }, +]; + +// setup +beforeEach(() => { + // mocks for orm + ormPMock.getAllPersons.mockResolvedValue(people); + ormPMock.createPerson.mockResolvedValue({ + name: "Test3", + person_id: 3, + email: "test3@mail.com", + github: null, + github_id: null, + }); + ormPMock.updatePerson.mockResolvedValue({ + name: "Test4", + person_id: 2, + email: "test2@mail.com", + github: null, + github_id: null, + }); +}); + +// reset +afterEach(() => { + ormPMock.getAllPersons.mockReset(); + ormPMock.createPerson.mockReset(); + ormPMock.updatePerson.mockReset(); +}); + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +test("Insert a person in the database (email not yet in the database)", async () => { + await expect( + addPersonToDatabase({ + name: "Test3", + email: "test3@mail.com", + }) + ).resolves.toStrictEqual({ + id: 3, + }); + + expectCall(ormP.createPerson, { + name: "Test3", + email: "test3@mail.com", + }); + + expect(ormP.getAllPersons).toHaveBeenCalledTimes(1); +}); + +test("Insert a person in the database (email already in the database)", async () => { + await expect( + addPersonToDatabase({ + name: "Test2", + email: "test2@mail.com", + }) + ).resolves.toStrictEqual({ + id: 2, + }); + + expectCall(ormP.updatePerson, { + name: "Test2", + personId: 2, + email: "test2@mail.com", + github: null, + }); + + expect(ormP.getAllPersons).toHaveBeenCalledTimes(1); +}); diff --git a/backend/tests/routes_unit/form/add_roles_to_database_files/add_roles_to_database.test.ts b/backend/tests/routes_unit/form/add_roles_to_database_files/add_roles_to_database.test.ts new file mode 100644 index 00000000..e8d1468f --- /dev/null +++ b/backend/tests/routes_unit/form/add_roles_to_database_files/add_roles_to_database.test.ts @@ -0,0 +1,48 @@ +import { addRolesToDatabase } from "../../../../routes/form"; + +import * as ormRo from "../../../../orm_functions/role"; +jest.mock("../../../../orm_functions/role"); +const ormRoMock = ormRo as jest.Mocked; + +import * as ormApRo from "../../../../orm_functions/applied_role"; +jest.mock("../../../../orm_functions/applied_role"); +const ormApRoMock = ormApRo as jest.Mocked; + +test("Insert attachments in the database", async () => { + ormRoMock.getRolesByName.mockResolvedValueOnce(null); + + ormRoMock.getRolesByName.mockResolvedValueOnce({ + role_id: 1, + name: "Back-end developer", + }); + + ormRoMock.createRole.mockResolvedValue({ + role_id: 1, + name: "Front-end developer", + }); + + ormApRoMock.createAppliedRole.mockResolvedValueOnce({ + applied_role_id: 1, + job_application_id: 1, + role_id: 1, + }); + + ormApRoMock.createAppliedRole.mockResolvedValueOnce({ + applied_role_id: 1, + job_application_id: 1, + role_id: 2, + }); + + await expect( + addRolesToDatabase( + { + roles: ["Front-end developer", "Back-end developer"], + }, + { id: 1 } + ) + ).resolves.toStrictEqual({}); + + ormRoMock.getRolesByName.mockReset(); + ormRoMock.createRole.mockReset(); + ormApRoMock.createAppliedRole.mockReset(); +}); diff --git a/backend/tests/routes_unit/form/add_skills_to_database_files/add_skills_to_database.test.ts b/backend/tests/routes_unit/form/add_skills_to_database_files/add_skills_to_database.test.ts new file mode 100644 index 00000000..1dc128c4 --- /dev/null +++ b/backend/tests/routes_unit/form/add_skills_to_database_files/add_skills_to_database.test.ts @@ -0,0 +1,126 @@ +import { addSkillsToDatabase } from "../../../../routes/form"; + +import * as ormJoSk from "../../../../orm_functions/job_application_skill"; +jest.mock("../../../../orm_functions/job_application_skill"); +const ormJoSkMock = ormJoSk as jest.Mocked; + +import * as ormLa from "../../../../orm_functions/language"; +jest.mock("../../../../orm_functions/language"); +const ormLaMock = ormLa as jest.Mocked; + +test("Insert job application skills in the database", async () => { + ormLaMock.getLanguageByName.mockResolvedValueOnce({ + name: "Dutch", + language_id: 1, + }); + + ormLaMock.getLanguageByName.mockResolvedValueOnce({ + name: "English", + language_id: 2, + }); + + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: null, + language_id: 1, + job_application_skill_id: 1, + level: null, + is_preferred: true, + is_best: false, + }); + + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: null, + language_id: 2, + job_application_skill_id: 2, + level: 4, + is_preferred: false, + is_best: false, + }); + + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: "Basketball", + language_id: null, + job_application_skill_id: 3, + level: null, + is_preferred: false, + is_best: true, + }); + + await expect( + addSkillsToDatabase( + { + most_fluent_language: "Dutch", + english_level: 4, + best_skill: "Basketball", + }, + { id: 1 } + ) + ).resolves.toStrictEqual({}); + + ormJoSkMock.createJobApplicationSkill.mockReset(); + ormLaMock.getLanguageByName.mockReset(); +}); + +test("Insert job application skills in the database (new languages)", async () => { + ormLaMock.getLanguageByName.mockResolvedValueOnce(null); + + ormLaMock.getLanguageByName.mockResolvedValueOnce(null); + + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: null, + language_id: 1, + job_application_skill_id: 1, + level: null, + is_preferred: true, + is_best: false, + }); + + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: null, + language_id: 2, + job_application_skill_id: 2, + level: 4, + is_preferred: false, + is_best: false, + }); + + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: "Basketball", + language_id: null, + job_application_skill_id: 3, + level: null, + is_preferred: false, + is_best: true, + }); + + ormLaMock.createLanguage.mockResolvedValueOnce({ + language_id: 1, + name: "Dutch", + }); + + ormLaMock.createLanguage.mockResolvedValueOnce({ + language_id: 2, + name: "English", + }); + + await expect( + addSkillsToDatabase( + { + most_fluent_language: "Dutch", + english_level: 4, + best_skill: "Basketball", + }, + { id: 1 } + ) + ).resolves.toStrictEqual({}); + + ormJoSkMock.createJobApplicationSkill.mockReset(); + ormLaMock.getLanguageByName.mockReset(); + ormLaMock.createLanguage.mockReset(); +}); diff --git a/backend/tests/routes_unit/form/add_student_to_database_files/add_student_to_database.test.ts b/backend/tests/routes_unit/form/add_student_to_database_files/add_student_to_database.test.ts new file mode 100644 index 00000000..6cb4e378 --- /dev/null +++ b/backend/tests/routes_unit/form/add_student_to_database_files/add_student_to_database.test.ts @@ -0,0 +1,232 @@ +import { student, person } from "@prisma/client"; + +import { addStudentToDatabase } from "../../../../routes/form"; + +import * as ormSt from "../../../../orm_functions/student"; +jest.mock("../../../../orm_functions/student"); +const ormStMock = ormSt as jest.Mocked; + +const students: (student & { person: person })[] = [ + { + student_id: 1, + person_id: 1, + gender: "M", + pronouns: "He/him/his", + phone_number: "0435721836", + nickname: "nick", + alumni: true, + person: { + person_id: 1, + name: "Test1", + email: "test1@mail.com", + github: null, + github_id: null, + }, + }, + { + student_id: 2, + person_id: 2, + gender: "V", + pronouns: "She/her/hers", + phone_number: "0481904236", + nickname: "nick2", + alumni: false, + person: { + person_id: 2, + name: "Test2", + email: "test2@mail.com", + github: null, + github_id: null, + }, + }, +]; + +// setup +beforeEach(() => { + // mocks for orm + ormStMock.getAllStudents.mockResolvedValue(students); + ormStMock.createStudent.mockResolvedValueOnce({ + student_id: 3, + person_id: 3, + gender: "M", + pronouns: "He/him/his", + phone_number: "0426719124", + nickname: "Nick3", + alumni: true, + }); + ormStMock.createStudent.mockResolvedValueOnce({ + student_id: 3, + person_id: 3, + gender: "M", + pronouns: null, + phone_number: "0426719124", + nickname: null, + alumni: true, + }); + ormStMock.updateStudent.mockResolvedValueOnce({ + student_id: 2, + person_id: 2, + gender: "M", + pronouns: "He/him/his", + phone_number: "0476124356", + nickname: "Nick4", + alumni: true, + person: { + person_id: 2, + name: "Test2", + email: "test2@mail.com", + github: null, + github_id: null, + }, + }); + ormStMock.updateStudent.mockResolvedValueOnce({ + student_id: 2, + person_id: 2, + gender: "M", + pronouns: null, + phone_number: "0476124356", + nickname: "Nick4", + alumni: true, + person: { + person_id: 2, + name: "Test2", + email: "test2@mail.com", + github: null, + github_id: null, + }, + }); +}); + +// reset +afterEach(() => { + ormStMock.getAllStudents.mockReset(); + ormStMock.createStudent.mockReset(); + ormStMock.updateStudent.mockReset(); +}); + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +test("Insert a student in the database (student not yet in the database), pronouns and nickname not null", async () => { + await expect( + addStudentToDatabase( + { + pronouns: "He/him/his", + gender: "M", + phoneNumber: "0426719124", + nickname: "Nick3", + alumni: true, + }, + { + id: 3, + } + ) + ).resolves.toStrictEqual({ + id: 3, + hasAlreadyTakenPart: true, + }); + + expectCall(ormSt.createStudent, { + personId: 3, + pronouns: "He/him/his", + gender: "M", + phoneNumber: "0426719124", + nickname: "Nick3", + alumni: true, + }); + + expect(ormSt.getAllStudents).toHaveBeenCalledTimes(1); +}); + +test("Insert a student in the database (student not yet in the database), pronouns and nickname null", async () => { + await expect( + addStudentToDatabase( + { + pronouns: null, + gender: "M", + phoneNumber: "0426719124", + nickname: null, + alumni: true, + }, + { + id: 3, + } + ) + ).resolves.toStrictEqual({ + id: 3, + hasAlreadyTakenPart: true, + }); + + expectCall(ormSt.createStudent, { + personId: 3, + gender: "M", + phoneNumber: "0426719124", + alumni: true, + }); + + expect(ormSt.getAllStudents).toHaveBeenCalledTimes(1); +}); + +test("Insert a student in the database (student already in the database), pronouns are not null", async () => { + await expect( + addStudentToDatabase( + { + pronouns: "He/him/his", + gender: "M", + phoneNumber: "0426719124", + nickname: "Nick3", + alumni: true, + }, + { + id: 2, + } + ) + ).resolves.toStrictEqual({ + id: 2, + hasAlreadyTakenPart: true, + }); + + expectCall(ormSt.updateStudent, { + studentId: 2, + pronouns: "He/him/his", + gender: "M", + phoneNumber: "0426719124", + nickname: "Nick3", + alumni: true, + }); + + expect(ormSt.getAllStudents).toHaveBeenCalledTimes(1); +}); + +test("Insert a student in the database (student already in the database), pronouns are null", async () => { + await expect( + addStudentToDatabase( + { + pronouns: null, + gender: "M", + phoneNumber: "0426719124", + nickname: "Nick3", + alumni: true, + }, + { + id: 2, + } + ) + ).resolves.toStrictEqual({ + id: 2, + hasAlreadyTakenPart: true, + }); + + expectCall(ormSt.updateStudent, { + studentId: 2, + pronouns: "", + gender: "M", + phoneNumber: "0426719124", + nickname: "Nick3", + alumni: true, + }); + + expect(ormSt.getAllStudents).toHaveBeenCalledTimes(1); +}); diff --git a/backend/tests/routes_unit/form/alumni_files/alumni.test.ts b/backend/tests/routes_unit/form/alumni_files/alumni.test.ts new file mode 100644 index 00000000..79c8f243 --- /dev/null +++ b/backend/tests/routes_unit/form/alumni_files/alumni.test.ts @@ -0,0 +1,28 @@ +import { errors } from "../../../../utility"; +import { getAlumni, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Alumni question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/alumni_files", + "alumniQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getAlumni(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Alumni options absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/alumni_files", + "alumniOptionsAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getAlumni(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/alumni_files/alumniOptionsAbsent.json b/backend/tests/routes_unit/form/alumni_files/alumniOptionsAbsent.json new file mode 100644 index 00000000..07f07174 --- /dev/null +++ b/backend/tests/routes_unit/form/alumni_files/alumniOptionsAbsent.json @@ -0,0 +1,714 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19" + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/alumni_files/alumniQuestionAbsent.json b/backend/tests/routes_unit/form/alumni_files/alumniQuestionAbsent.json new file mode 100644 index 00000000..e6139a37 --- /dev/null +++ b/backend/tests/routes_unit/form/alumni_files/alumniQuestionAbsent.json @@ -0,0 +1,708 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/applied_roles_files/appliedRolesOtherOptionValid.json b/backend/tests/routes_unit/form/applied_roles_files/appliedRolesOtherOptionValid.json new file mode 100644 index 00000000..75d6fb9b --- /dev/null +++ b/backend/tests/routes_unit/form/applied_roles_files/appliedRolesOtherOptionValid.json @@ -0,0 +1,699 @@ +{ + "eventId": "a8483798-b4cc-4e3b-88ec-870136db3f1b", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-14T19:01:22.092Z", + "data": { + "responseId": "mZWKaA", + "submissionId": "mZWKaA", + "respondentId": "mZR79a", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-14T19:01:21.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "A" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "https://www.youtube.com/watch?v=o-YBDTqX_ZU&ab_channel=MusRest" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "1@test.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "TEST" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": "Esports" + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "25c435fd-f20a-4e70-bafd-0563089e28ec" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 7 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1st" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "KU Leuven" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "dede10c8-a949-463c-8ae8-73f6fab6a362" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": "Gamer" + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Gaming" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/applied_roles_files/applied_roles.test.ts b/backend/tests/routes_unit/form/applied_roles_files/applied_roles.test.ts new file mode 100644 index 00000000..a1d7a7c6 --- /dev/null +++ b/backend/tests/routes_unit/form/applied_roles_files/applied_roles.test.ts @@ -0,0 +1,65 @@ +import { errors } from "../../../../utility"; + +import { getAppliedRoles, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Applied roles question value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/applied_roles_files", + "failAppliedRolesValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getAppliedRoles(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Applied roles other question value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/applied_roles_files", + "failAppliedRolesOtherValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getAppliedRoles(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Applied roles question value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/applied_roles_files", + "failAppliedRolesOptions.json" + ); + expect(data).not.toBeNull(); + + await expect(getAppliedRoles(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Applied roles other option value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/applied_roles_files", + "failAppliedRolesOtherOptionValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getAppliedRoles(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Applied roles other option value is valid", async () => { + const data = await readFile( + "../tests/routes_unit/form/applied_roles_files", + "appliedRolesOtherOptionValid.json" + ); + expect(data).not.toBeNull(); + + await expect(getAppliedRoles(data as Form)).resolves.toStrictEqual([ + "Gamer", + ]); +}); diff --git a/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOptions.json b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOptions.json new file mode 100644 index 00000000..aad20a31 --- /dev/null +++ b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOptions.json @@ -0,0 +1,699 @@ +{ + "eventId": "a8483798-b4cc-4e3b-88ec-870136db3f1b", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-14T19:01:22.092Z", + "data": { + "responseId": "mZWKaA", + "submissionId": "mZWKaA", + "respondentId": "mZR79a", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-14T19:01:21.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "A" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "https://www.youtube.com/watch?v=o-YBDTqX_ZU&ab_channel=MusRest" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "1@test.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "TEST" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": "Esports" + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "25c435fd-f20a-4e70-bafd-0563089e28ec" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 7 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1st" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "KU Leuven" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "d2c3e561-28bd-4de9-a7db-00cd22beb3b7" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": "Gamer" + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Gaming" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOtherOptionValueNull.json b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOtherOptionValueNull.json new file mode 100644 index 00000000..027d064e --- /dev/null +++ b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOtherOptionValueNull.json @@ -0,0 +1,699 @@ +{ + "eventId": "a8483798-b4cc-4e3b-88ec-870136db3f1b", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-14T19:01:22.092Z", + "data": { + "responseId": "mZWKaA", + "submissionId": "mZWKaA", + "respondentId": "mZR79a", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-14T19:01:21.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "A" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "https://www.youtube.com/watch?v=o-YBDTqX_ZU&ab_channel=MusRest" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "1@test.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "TEST" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": "Esports" + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "25c435fd-f20a-4e70-bafd-0563089e28ec" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 7 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1st" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "KU Leuven" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "dede10c8-a949-463c-8ae8-73f6fab6a362" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Gaming" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOtherValueNull.json b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOtherValueNull.json new file mode 100644 index 00000000..478a8c01 --- /dev/null +++ b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesOtherValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "dede10c8-a949-463c-8ae8-73f6fab6a362" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesValueNull.json b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesValueNull.json new file mode 100644 index 00000000..1ab25ac5 --- /dev/null +++ b/backend/tests/routes_unit/form/applied_roles_files/failAppliedRolesValueNull.json @@ -0,0 +1,697 @@ +{ + "eventId": "a8483798-b4cc-4e3b-88ec-870136db3f1b", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-14T19:01:22.092Z", + "data": { + "responseId": "mZWKaA", + "submissionId": "mZWKaA", + "respondentId": "mZR79a", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-14T19:01:21.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "A" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "https://www.youtube.com/watch?v=o-YBDTqX_ZU&ab_channel=MusRest" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "1@test.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "TEST" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": "Esports" + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "25c435fd-f20a-4e70-bafd-0563089e28ec" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 7 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1st" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "KU Leuven" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": null, + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": "Gamer" + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Gaming" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/best_skill_files/bestSkillQuestionAbsent.json b/backend/tests/routes_unit/form/best_skill_files/bestSkillQuestionAbsent.json new file mode 100644 index 00000000..0153a3e5 --- /dev/null +++ b/backend/tests/routes_unit/form/best_skill_files/bestSkillQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/best_skill_files/best_skill.test.ts b/backend/tests/routes_unit/form/best_skill_files/best_skill.test.ts new file mode 100644 index 00000000..9beec53f --- /dev/null +++ b/backend/tests/routes_unit/form/best_skill_files/best_skill.test.ts @@ -0,0 +1,17 @@ +import { errors } from "../../../../utility"; + +import { getBestSkill, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Best skill question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/best_skill_files", + "bestSkillQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getBestSkill(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/birth_name_files/birth_name.test.ts b/backend/tests/routes_unit/form/birth_name_files/birth_name.test.ts new file mode 100644 index 00000000..92ded052 --- /dev/null +++ b/backend/tests/routes_unit/form/birth_name_files/birth_name.test.ts @@ -0,0 +1,23 @@ +import { errors } from "../../../../utility"; + +import { getBirthName, readFile } from "../../../../routes/form"; + +test("Birth name question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/birth_name_files", + "failBirthNameQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getBirthName(data)).rejects.toBe(errors.cookArgumentError()); +}); + +test("Birth name value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/birth_name_files", + "failBirthNameValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getBirthName(data)).rejects.toBe(errors.cookArgumentError()); +}); diff --git a/backend/tests/routes_unit/form/birth_name_files/failBirthNameQuestionAbsent.json b/backend/tests/routes_unit/form/birth_name_files/failBirthNameQuestionAbsent.json new file mode 100644 index 00000000..a1418e20 --- /dev/null +++ b/backend/tests/routes_unit/form/birth_name_files/failBirthNameQuestionAbsent.json @@ -0,0 +1,719 @@ +{ + "eventId": "a76c750d-2c0c-4e5f-8f90-26044bf6b719", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:07:36.289Z", + "data": { + "responseId": "meP9Wk", + "submissionId": "meP9Wk", + "respondentId": "wbN9X2", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:07:36.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I am irresponsible" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Lee" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": "Latin" + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "+2469420420" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "mohammed.lee@hotmail.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mBKNO4", + "name": "cursed-pacman.png", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/fb099019-5cc0-4e14-98ec-e108afda126e/cursed-pacman.png", + "mimeType": "image/png", + "size": 918931 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "wvrk7X", + "name": "dnd_d10000.pdf", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/f37a3389-26f7-4572-9fa1-92bee7a138a2/dnd_d10000.pdf", + "mimeType": "application/pdf", + "size": 628988 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mKeb7z", + "name": "openapi.yaml", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/5a5464fa-8f28-43da-b9ea-bc5e6d44c787/openapi.yaml", + "mimeType": "application/x-yaml", + "size": 75536 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I have the world's most common name!" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "c2c15641-dee6-4712-8fdf-0448d2dcaed1" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 3 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "Stan Lee's University for Comedians" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "def165c9-d40a-4d13-b174-98d480e1dd41", + "e993e2bb-6dfe-4ec3-8f36-cf940b30533e" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Having the world's most common name *dabs*" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/birth_name_files/failBirthNameValueNull.json b/backend/tests/routes_unit/form/birth_name_files/failBirthNameValueNull.json new file mode 100644 index 00000000..4a37ed8e --- /dev/null +++ b/backend/tests/routes_unit/form/birth_name_files/failBirthNameValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/create_form_files/allValidForm.json b/backend/tests/routes_unit/form/create_form_files/allValidForm.json new file mode 100644 index 00000000..94f724ab --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/allValidForm.json @@ -0,0 +1,701 @@ +{ + "eventId": "e5ecc6fc-cdcf-445d-8900-d5f951edf7c8", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-14T18:15:30.245Z", + "data": { + "responseId": "wMPqeX", + "submissionId": "wMPqeX", + "respondentId": "3NBEQB", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-14T18:15:30.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "not really, I'm available the whole day" + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Bram" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Devlaminck" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": "him" + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": "English" + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "+32 477 47 47 47" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "T.h.i.s.i.s.a.t.e.s.t.m.a.i.l@gmail.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I like running and baking" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": "baking" + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 3 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "backend development" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/create_form_files/create_form.test.ts b/backend/tests/routes_unit/form/create_form_files/create_form.test.ts new file mode 100644 index 00000000..b5229498 --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/create_form.test.ts @@ -0,0 +1,247 @@ +import { getMockReq } from "@jest-mock/express"; + +import express from "express"; +import { errors } from "../../../../utility"; +import { createForm, readFile } from "../../../../routes/form"; + +import * as ormOs from "../../../../orm_functions/osoc"; +import { job_application, osoc } from "@prisma/client"; +jest.mock("../../../../orm_functions/osoc"); +const ormOsMock = ormOs as jest.Mocked; + +import * as ormJo from "../../../../orm_functions/job_application"; +jest.mock("../../../../orm_functions/job_application"); +const ormJoMock = ormJo as jest.Mocked; + +import * as ormP from "../../../../orm_functions/person"; +jest.mock("../../../../orm_functions/person"); +const ormPMock = ormP as jest.Mocked; + +import * as ormSt from "../../../../orm_functions/student"; +jest.mock("../../../../orm_functions/student"); +const ormStMock = ormSt as jest.Mocked; + +import * as ormL from "../../../../orm_functions/language"; +jest.mock("../../../../orm_functions/language"); +const ormLMock = ormL as jest.Mocked; + +import * as ormJoSk from "../../../../orm_functions/job_application_skill"; +jest.mock("../../../../orm_functions/job_application_skill"); +const ormJoSkMock = ormJoSk as jest.Mocked; + +import * as ormRo from "../../../../orm_functions/role"; +jest.mock("../../../../orm_functions/role"); +const ormRoMock = ormRo as jest.Mocked; + +import * as ormAppRo from "../../../../orm_functions/applied_role"; +jest.mock("../../../../orm_functions/applied_role"); +const ormAppRoMock = ormAppRo as jest.Mocked; + +const jobApplication: job_application = { + job_application_id: 1, + student_id: 1, + student_volunteer_info: "Yes, I can work as a volunteer in Belgium", + responsibilities: "not really, I'm available the whole day", + fun_fact: "I like running and baking", + student_coach: false, + osoc_id: 1, + edus: ["Computer Sciences", "baking"], + edu_level: "An academic Bachelor", + edu_duration: 3, + edu_year: "3", + edu_institute: "UGent", + email_status: "APPLIED", + created_at: new Date("2022-04-14T18:15:30.245Z"), +}; + +test("Live in Belgium question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "failLiveInBelgiumAbsent.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).rejects.toBe(errors.cookArgumentError()); +}); + +test("Live in Belgium value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "failLiveInBelgiumValueNull.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).rejects.toBe(errors.cookArgumentError()); +}); + +test("Work in july value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "failWorkInJulyValueNull.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).rejects.toBe(errors.cookArgumentError()); +}); + +test("Work in July question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "failWorkInJulyAbsent.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).rejects.toBe(errors.cookArgumentError()); +}); + +test("Work in July 'no' answer", async () => { + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "liveInBelgiumAnswerNo.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).resolves.toStrictEqual({}); +}); + +test("Work in July 'null' answer", async () => { + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "liveInBelgiumAnswerNull.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).resolves.toStrictEqual({}); +}); + +test("No osoc year specified", async () => { + mockDatabaseCalls(null); + + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "allValidForm.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).rejects.toBe(errors.cookArgumentError()); + + resetDatabaseCalls(); +}); + +function mockDatabaseCalls(latestOsocValue: osoc | null) { + ormPMock.searchPersonByLogin.mockResolvedValue([]); + ormOsMock.getLatestOsoc.mockResolvedValue(latestOsocValue); + ormPMock.getAllPersons.mockResolvedValue([]); + ormPMock.createPerson.mockResolvedValue({ + name: "Bram Devlaminck", + person_id: 1, + email: "T.h.i.s.i.s.a.t.e.s.t.m.a.i.l@gmail.com", + github: null, + github_id: null, + }); + ormStMock.getAllStudents.mockResolvedValue([]); + ormStMock.createStudent.mockResolvedValue({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "+32 477 47 47 47", + nickname: null, + alumni: true, + }); + ormJoMock.getLatestJobApplicationOfStudent.mockResolvedValue(null); + ormJoMock.createJobApplication.mockResolvedValue(jobApplication); + ormLMock.getLanguageByName.mockResolvedValueOnce({ + language_id: 1, + name: "Dutch", + }); + ormLMock.getLanguageByName.mockResolvedValueOnce({ + language_id: 2, + name: "English", + }); + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: null, + language_id: 2, + job_application_skill_id: 1, + level: 4, + is_preferred: false, + is_best: false, + }); + + ormJoSkMock.createJobApplicationSkill.mockResolvedValueOnce({ + job_application_id: 1, + skill: "backend development", + language_id: null, + job_application_skill_id: 2, + level: null, + is_preferred: false, + is_best: true, + }); + ormRoMock.getRolesByName.mockResolvedValueOnce({ + role_id: 1, + name: "Front-end developer", + }); + ormRoMock.getRolesByName.mockResolvedValueOnce({ + role_id: 2, + name: "Back-end developer", + }); + ormAppRoMock.createAppliedRole.mockResolvedValueOnce({ + applied_role_id: 1, + job_application_id: 1, + role_id: 1, + }); + ormAppRoMock.createAppliedRole.mockResolvedValueOnce({ + applied_role_id: 2, + job_application_id: 1, + role_id: 2, + }); +} + +function resetDatabaseCalls() { + ormPMock.searchPersonByLogin.mockReset(); + ormOsMock.getLatestOsoc.mockReset(); + ormPMock.getAllPersons.mockReset(); + ormPMock.createPerson.mockReset(); + ormStMock.getAllStudents.mockReset(); + ormStMock.createStudent.mockReset(); + ormJoMock.getLatestJobApplicationOfStudent.mockReset(); + ormJoMock.createJobApplication.mockReset(); + ormLMock.getLanguageByName.mockReset(); + ormJoSkMock.createJobApplicationSkill.mockReset(); + ormRoMock.getRolesByName.mockReset(); + ormAppRoMock.createAppliedRole.mockReset(); +} + +test("Osoc year specified", async () => { + mockDatabaseCalls({ + osoc_id: 1, + year: 2023, + }); + + const data = await readFile( + "../tests/routes_unit/form/create_form_files", + "allValidForm.json" + ); + expect(data).not.toBeNull(); + + const req: express.Request = getMockReq(); + req.body = { ...data }; + await expect(createForm(req)).resolves.toStrictEqual({}); + + resetDatabaseCalls(); +}); diff --git a/backend/tests/routes_unit/form/create_form_files/failLiveInBelgiumAbsent.json b/backend/tests/routes_unit/form/create_form_files/failLiveInBelgiumAbsent.json new file mode 100644 index 00000000..37bdd01d --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/failLiveInBelgiumAbsent.json @@ -0,0 +1,709 @@ +{ + "eventId": "a76c750d-2c0c-4e5f-8f90-26044bf6b719", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:07:36.289Z", + "data": { + "responseId": "meP9Wk", + "submissionId": "meP9Wk", + "respondentId": "wbN9X2", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:07:36.000Z", + "fields": [ + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I am irresponsible" + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Mohammed" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Lee" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": "Latin" + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "+2469420420" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "mohammed.lee@hotmail.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mBKNO4", + "name": "cursed-pacman.png", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/fb099019-5cc0-4e14-98ec-e108afda126e/cursed-pacman.png", + "mimeType": "image/png", + "size": 918931 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "wvrk7X", + "name": "dnd_d10000.pdf", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/f37a3389-26f7-4572-9fa1-92bee7a138a2/dnd_d10000.pdf", + "mimeType": "application/pdf", + "size": 628988 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mKeb7z", + "name": "openapi.yaml", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/5a5464fa-8f28-43da-b9ea-bc5e6d44c787/openapi.yaml", + "mimeType": "application/x-yaml", + "size": 75536 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I have the world's most common name!" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "c2c15641-dee6-4712-8fdf-0448d2dcaed1" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 3 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "Stan Lee's University for Comedians" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "def165c9-d40a-4d13-b174-98d480e1dd41", + "e993e2bb-6dfe-4ec3-8f36-cf940b30533e" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Having the world's most common name *dabs*" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/create_form_files/failLiveInBelgiumValueNull.json b/backend/tests/routes_unit/form/create_form_files/failLiveInBelgiumValueNull.json new file mode 100644 index 00000000..b0cc2d26 --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/failLiveInBelgiumValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/create_form_files/failWorkInJulyAbsent.json b/backend/tests/routes_unit/form/create_form_files/failWorkInJulyAbsent.json new file mode 100644 index 00000000..1de6819e --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/failWorkInJulyAbsent.json @@ -0,0 +1,709 @@ +{ + "eventId": "a76c750d-2c0c-4e5f-8f90-26044bf6b719", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:07:36.289Z", + "data": { + "responseId": "meP9Wk", + "submissionId": "meP9Wk", + "respondentId": "wbN9X2", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:07:36.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I am irresponsible" + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Mohammed" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Lee" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": "Latin" + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "+2469420420" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "mohammed.lee@hotmail.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mBKNO4", + "name": "cursed-pacman.png", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/fb099019-5cc0-4e14-98ec-e108afda126e/cursed-pacman.png", + "mimeType": "image/png", + "size": 918931 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "wvrk7X", + "name": "dnd_d10000.pdf", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/f37a3389-26f7-4572-9fa1-92bee7a138a2/dnd_d10000.pdf", + "mimeType": "application/pdf", + "size": 628988 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mKeb7z", + "name": "openapi.yaml", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/5a5464fa-8f28-43da-b9ea-bc5e6d44c787/openapi.yaml", + "mimeType": "application/x-yaml", + "size": 75536 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I have the world's most common name!" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "c2c15641-dee6-4712-8fdf-0448d2dcaed1" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 3 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "Stan Lee's University for Comedians" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "def165c9-d40a-4d13-b174-98d480e1dd41", + "e993e2bb-6dfe-4ec3-8f36-cf940b30533e" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Having the world's most common name *dabs*" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/create_form_files/failWorkInJulyValueNull.json b/backend/tests/routes_unit/form/create_form_files/failWorkInJulyValueNull.json new file mode 100644 index 00000000..dfdfdd23 --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/failWorkInJulyValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/create_form_files/liveInBelgiumAnswerNo.json b/backend/tests/routes_unit/form/create_form_files/liveInBelgiumAnswerNo.json new file mode 100644 index 00000000..af283a9e --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/liveInBelgiumAnswerNo.json @@ -0,0 +1,725 @@ +{ + "eventId": "a76c750d-2c0c-4e5f-8f90-26044bf6b719", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:07:36.289Z", + "data": { + "responseId": "meP9Wk", + "submissionId": "meP9Wk", + "respondentId": "wbN9X2", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:07:36.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I am irresponsible" + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Mohammed" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Lee" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": "Latin" + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "+2469420420" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "mohammed.lee@hotmail.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mBKNO4", + "name": "cursed-pacman.png", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/fb099019-5cc0-4e14-98ec-e108afda126e/cursed-pacman.png", + "mimeType": "image/png", + "size": 918931 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "wvrk7X", + "name": "dnd_d10000.pdf", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/f37a3389-26f7-4572-9fa1-92bee7a138a2/dnd_d10000.pdf", + "mimeType": "application/pdf", + "size": 628988 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mKeb7z", + "name": "openapi.yaml", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/5a5464fa-8f28-43da-b9ea-bc5e6d44c787/openapi.yaml", + "mimeType": "application/x-yaml", + "size": 75536 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I have the world's most common name!" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "c2c15641-dee6-4712-8fdf-0448d2dcaed1" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 3 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "Stan Lee's University for Comedians" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "def165c9-d40a-4d13-b174-98d480e1dd41", + "e993e2bb-6dfe-4ec3-8f36-cf940b30533e" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Having the world's most common name *dabs*" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/create_form_files/liveInBelgiumAnswerNull.json b/backend/tests/routes_unit/form/create_form_files/liveInBelgiumAnswerNull.json new file mode 100644 index 00000000..4fd89001 --- /dev/null +++ b/backend/tests/routes_unit/form/create_form_files/liveInBelgiumAnswerNull.json @@ -0,0 +1,725 @@ +{ + "eventId": "a76c750d-2c0c-4e5f-8f90-26044bf6b719", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:07:36.289Z", + "data": { + "responseId": "meP9Wk", + "submissionId": "meP9Wk", + "respondentId": "wbN9X2", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:07:36.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "wrong value", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I am irresponsible" + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Mohammed" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Lee" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": "Latin" + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "+2469420420" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "mohammed.lee@hotmail.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mBKNO4", + "name": "cursed-pacman.png", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/fb099019-5cc0-4e14-98ec-e108afda126e/cursed-pacman.png", + "mimeType": "image/png", + "size": 918931 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "wvrk7X", + "name": "dnd_d10000.pdf", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/f37a3389-26f7-4572-9fa1-92bee7a138a2/dnd_d10000.pdf", + "mimeType": "application/pdf", + "size": 628988 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mKeb7z", + "name": "openapi.yaml", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/5a5464fa-8f28-43da-b9ea-bc5e6d44c787/openapi.yaml", + "mimeType": "application/x-yaml", + "size": 75536 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I have the world's most common name!" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "c2c15641-dee6-4712-8fdf-0448d2dcaed1" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 3 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "Stan Lee's University for Comedians" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "def165c9-d40a-4d13-b174-98d480e1dd41", + "e993e2bb-6dfe-4ec3-8f36-cf940b30533e" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Having the world's most common name *dabs*" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/cv_files/cv.test.ts b/backend/tests/routes_unit/form/cv_files/cv.test.ts new file mode 100644 index 00000000..a8583499 --- /dev/null +++ b/backend/tests/routes_unit/form/cv_files/cv.test.ts @@ -0,0 +1,55 @@ +import { errors } from "../../../../utility"; + +import { getCV, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("The cv link question is absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/cv_files", + "cvLinkQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getCV(data as Form)).rejects.toBe(errors.cookArgumentError()); +}); + +test("The value of the cv link question is not empty", async () => { + const data = await readFile( + "../tests/routes_unit/form/cv_files", + "cvLinkValueNotEmpty.json" + ); + expect(data).not.toBeNull(); + + await expect(getCV(data as Form)).resolves.toStrictEqual({ + data: [ + "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + ], + types: ["CV_URL"], + }); +}); + +test("The url field in the cv upload question is undefined", async () => { + const data = await readFile( + "../tests/routes_unit/form/cv_files", + "cvUrlNotDefined.json" + ); + expect(data).not.toBeNull(); + + await expect(getCV(data as Form)).rejects.toBe(errors.cookArgumentError()); +}); + +test("The value of the cv upload field is valid", async () => { + const data = await readFile( + "../tests/routes_unit/form/cv_files", + "cvUploadValueValid.json" + ); + expect(data).not.toBeNull(); + + await expect(getCV(data as Form)).resolves.toStrictEqual({ + data: [ + "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + ], + types: ["CV_URL"], + }); +}); diff --git a/backend/tests/routes_unit/form/cv_files/cvLinkQuestionAbsent.json b/backend/tests/routes_unit/form/cv_files/cvLinkQuestionAbsent.json new file mode 100644 index 00000000..77bfb8a2 --- /dev/null +++ b/backend/tests/routes_unit/form/cv_files/cvLinkQuestionAbsent.json @@ -0,0 +1,702 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/cv_files/cvLinkValueNotEmpty.json b/backend/tests/routes_unit/form/cv_files/cvLinkValueNotEmpty.json new file mode 100644 index 00000000..52756013 --- /dev/null +++ b/backend/tests/routes_unit/form/cv_files/cvLinkValueNotEmpty.json @@ -0,0 +1,700 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt" + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt" + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/cv_files/cvUploadValueValid.json b/backend/tests/routes_unit/form/cv_files/cvUploadValueValid.json new file mode 100644 index 00000000..785453b6 --- /dev/null +++ b/backend/tests/routes_unit/form/cv_files/cvUploadValueValid.json @@ -0,0 +1,708 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/cv_files/cvUrlNotDefined.json b/backend/tests/routes_unit/form/cv_files/cvUrlNotDefined.json new file mode 100644 index 00000000..4961aa22 --- /dev/null +++ b/backend/tests/routes_unit/form/cv_files/cvUrlNotDefined.json @@ -0,0 +1,707 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_duration_files/educationDurationQuestionAbsent.json b/backend/tests/routes_unit/form/education_duration_files/educationDurationQuestionAbsent.json new file mode 100644 index 00000000..3bc27f9f --- /dev/null +++ b/backend/tests/routes_unit/form/education_duration_files/educationDurationQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_duration_files/educationDurationValueNull.json b/backend/tests/routes_unit/form/education_duration_files/educationDurationValueNull.json new file mode 100644 index 00000000..0ad8896a --- /dev/null +++ b/backend/tests/routes_unit/form/education_duration_files/educationDurationValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": null + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_duration_files/education_duration.test.ts b/backend/tests/routes_unit/form/education_duration_files/education_duration.test.ts new file mode 100644 index 00000000..d2495393 --- /dev/null +++ b/backend/tests/routes_unit/form/education_duration_files/education_duration.test.ts @@ -0,0 +1,28 @@ +import { errors } from "../../../../utility"; +import { getEducationDuration, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Education duration question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_duration_files", + "educationDurationQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationDuration(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Education duration value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_duration_files", + "educationDurationValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationDuration(data as Form)).resolves.toStrictEqual( + null + ); +}); diff --git a/backend/tests/routes_unit/form/education_institute_files/educationInstituteQuestionAbsent.json b/backend/tests/routes_unit/form/education_institute_files/educationInstituteQuestionAbsent.json new file mode 100644 index 00000000..7f002a0c --- /dev/null +++ b/backend/tests/routes_unit/form/education_institute_files/educationInstituteQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_institute_files/educationInstituteValueNull.json b/backend/tests/routes_unit/form/education_institute_files/educationInstituteValueNull.json new file mode 100644 index 00000000..51cebbbb --- /dev/null +++ b/backend/tests/routes_unit/form/education_institute_files/educationInstituteValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_institute_files/education_institute.test.ts b/backend/tests/routes_unit/form/education_institute_files/education_institute.test.ts new file mode 100644 index 00000000..202a9d8e --- /dev/null +++ b/backend/tests/routes_unit/form/education_institute_files/education_institute.test.ts @@ -0,0 +1,28 @@ +import { errors } from "../../../../utility"; +import { getEducationUniversity, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Education institute question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_institute_files", + "educationInstituteQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationUniversity(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Education institute value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_institute_files", + "educationInstituteValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationUniversity(data as Form)).resolves.toStrictEqual( + null + ); +}); diff --git a/backend/tests/routes_unit/form/education_level_files/educationLevelOptionsAbsent.json b/backend/tests/routes_unit/form/education_level_files/educationLevelOptionsAbsent.json new file mode 100644 index 00000000..9540586d --- /dev/null +++ b/backend/tests/routes_unit/form/education_level_files/educationLevelOptionsAbsent.json @@ -0,0 +1,694 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_level_files/educationLevelOptionsWithSameId.json b/backend/tests/routes_unit/form/education_level_files/educationLevelOptionsWithSameId.json new file mode 100644 index 00000000..147d5ddf --- /dev/null +++ b/backend/tests/routes_unit/form/education_level_files/educationLevelOptionsWithSameId.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_level_files/educationLevelOtherQuestionAbsent.json b/backend/tests/routes_unit/form/education_level_files/educationLevelOtherQuestionAbsent.json new file mode 100644 index 00000000..5eabb20c --- /dev/null +++ b/backend/tests/routes_unit/form/education_level_files/educationLevelOtherQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "67e44797-6696-4605-b1bd-bf76859c70f9" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_level_files/educationLevelOtherQuestionNotNull.json b/backend/tests/routes_unit/form/education_level_files/educationLevelOtherQuestionNotNull.json new file mode 100644 index 00000000..27673df5 --- /dev/null +++ b/backend/tests/routes_unit/form/education_level_files/educationLevelOtherQuestionNotNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "67e44797-6696-4605-b1bd-bf76859c70f9" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": "No diploma" + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_level_files/educationLevelQuestionAbsent.json b/backend/tests/routes_unit/form/education_level_files/educationLevelQuestionAbsent.json new file mode 100644 index 00000000..968d7556 --- /dev/null +++ b/backend/tests/routes_unit/form/education_level_files/educationLevelQuestionAbsent.json @@ -0,0 +1,686 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_level_files/education_level.test.ts b/backend/tests/routes_unit/form/education_level_files/education_level.test.ts new file mode 100644 index 00000000..149342c8 --- /dev/null +++ b/backend/tests/routes_unit/form/education_level_files/education_level.test.ts @@ -0,0 +1,64 @@ +import { errors } from "../../../../utility"; +import { getEducationLevel, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Education level question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_level_files", + "educationLevelQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationLevel(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Education level options with the same id", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_level_files", + "educationLevelOptionsWithSameId.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationLevel(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Education level other question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_level_files", + "educationLevelOtherQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationLevel(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Education level other question value not null", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_level_files", + "educationLevelOtherQuestionNotNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationLevel(data as Form)).resolves.toStrictEqual( + "No diploma" + ); +}); + +test("Education level options absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_level_files", + "educationLevelOptionsAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationLevel(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/education_year_files/educationYearQuestionAbsent.json b/backend/tests/routes_unit/form/education_year_files/educationYearQuestionAbsent.json new file mode 100644 index 00000000..0e24caa1 --- /dev/null +++ b/backend/tests/routes_unit/form/education_year_files/educationYearQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_year_files/educationYearValueNull.json b/backend/tests/routes_unit/form/education_year_files/educationYearValueNull.json new file mode 100644 index 00000000..ba8b29e3 --- /dev/null +++ b/backend/tests/routes_unit/form/education_year_files/educationYearValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/education_year_files/education_year.test.ts b/backend/tests/routes_unit/form/education_year_files/education_year.test.ts new file mode 100644 index 00000000..bb1013e3 --- /dev/null +++ b/backend/tests/routes_unit/form/education_year_files/education_year.test.ts @@ -0,0 +1,26 @@ +import { errors } from "../../../../utility"; +import { getEducationYear, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Education year question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_year_files", + "educationYearQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationYear(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Education year value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/education_year_files", + "educationYearValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducationYear(data as Form)).resolves.toStrictEqual(null); +}); diff --git a/backend/tests/routes_unit/form/educations_files/educations.test.ts b/backend/tests/routes_unit/form/educations_files/educations.test.ts new file mode 100644 index 00000000..09bbecbd --- /dev/null +++ b/backend/tests/routes_unit/form/educations_files/educations.test.ts @@ -0,0 +1,40 @@ +import { errors } from "../../../../utility"; +import { getEducations, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Educations question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/educations_files", + "educationsQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducations(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Educations options have the same value", async () => { + const data = await readFile( + "../tests/routes_unit/form/educations_files", + "educationsOptionsWithSameId.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducations(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Educations other question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/educations_files", + "educationsOtherQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEducations(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/educations_files/educationsOptionsWithSameId.json b/backend/tests/routes_unit/form/educations_files/educationsOptionsWithSameId.json new file mode 100644 index 00000000..bb6addd7 --- /dev/null +++ b/backend/tests/routes_unit/form/educations_files/educationsOptionsWithSameId.json @@ -0,0 +1,723 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/educations_files/educationsOtherQuestionAbsent.json b/backend/tests/routes_unit/form/educations_files/educationsOtherQuestionAbsent.json new file mode 100644 index 00000000..8d115c87 --- /dev/null +++ b/backend/tests/routes_unit/form/educations_files/educationsOtherQuestionAbsent.json @@ -0,0 +1,717 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/educations_files/educationsQuestionAbsent.json b/backend/tests/routes_unit/form/educations_files/educationsQuestionAbsent.json new file mode 100644 index 00000000..cac95d87 --- /dev/null +++ b/backend/tests/routes_unit/form/educations_files/educationsQuestionAbsent.json @@ -0,0 +1,673 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/email_files/email.test.ts b/backend/tests/routes_unit/form/email_files/email.test.ts new file mode 100644 index 00000000..dcfc1c0a --- /dev/null +++ b/backend/tests/routes_unit/form/email_files/email.test.ts @@ -0,0 +1,65 @@ +import { errors } from "../../../../utility"; +import { getEmail, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +import * as ormP from "../../../../orm_functions/person"; +jest.mock("../../../../orm_functions/person"); +const ormPMock = ormP as jest.Mocked; + +import * as ormLu from "../../../../orm_functions/login_user"; +jest.mock("../../../../orm_functions/login_user"); +const ormLuMock = ormLu as jest.Mocked; + +test("Email question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/email_files", + "emailQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEmail(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Email person already in the database", async () => { + ormPMock.searchPersonByLogin.mockResolvedValue([ + { + name: "Lucas Chen", + person_id: 1, + email: "lucas.chen@student.com", + github: null, + github_id: null, + }, + ]); + + ormLuMock.searchLoginUserByPerson.mockResolvedValue({ + login_user_id: 1, + person_id: 1, + password: "pass", + is_admin: true, + is_coach: true, + account_status: "ACTIVATED", + person: { + name: "Lucas Chen", + person_id: 1, + email: "lucas.chen@student.com", + github: null, + github_id: null, + }, + }); + + const data = await readFile( + "../tests/routes_unit/form/email_files", + "emailAlreadyInDatabase.json" + ); + expect(data).not.toBeNull(); + + await expect(getEmail(data as Form)).rejects.toBe( + errors.cookInsufficientRights() + ); + + ormPMock.searchPersonByLogin.mockReset(); + ormLuMock.searchLoginUserByPerson.mockReset(); +}); diff --git a/backend/tests/routes_unit/form/email_files/emailAlreadyInDatabase.json b/backend/tests/routes_unit/form/email_files/emailAlreadyInDatabase.json new file mode 100644 index 00000000..f3dbfa18 --- /dev/null +++ b/backend/tests/routes_unit/form/email_files/emailAlreadyInDatabase.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/email_files/emailQuestionAbsent.json b/backend/tests/routes_unit/form/email_files/emailQuestionAbsent.json new file mode 100644 index 00000000..aa7da475 --- /dev/null +++ b/backend/tests/routes_unit/form/email_files/emailQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/english_level_files/englishLevelOptionsAbsent.json b/backend/tests/routes_unit/form/english_level_files/englishLevelOptionsAbsent.json new file mode 100644 index 00000000..4757a870 --- /dev/null +++ b/backend/tests/routes_unit/form/english_level_files/englishLevelOptionsAbsent.json @@ -0,0 +1,702 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf" + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/english_level_files/englishLevelQuestionAbsent.json b/backend/tests/routes_unit/form/english_level_files/englishLevelQuestionAbsent.json new file mode 100644 index 00000000..794d6071 --- /dev/null +++ b/backend/tests/routes_unit/form/english_level_files/englishLevelQuestionAbsent.json @@ -0,0 +1,696 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/english_level_files/englishLevelStars.json b/backend/tests/routes_unit/form/english_level_files/englishLevelStars.json new file mode 100644 index 00000000..891b239a --- /dev/null +++ b/backend/tests/routes_unit/form/english_level_files/englishLevelStars.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/english_level_files/english_level.test.ts b/backend/tests/routes_unit/form/english_level_files/english_level.test.ts new file mode 100644 index 00000000..61ed7f66 --- /dev/null +++ b/backend/tests/routes_unit/form/english_level_files/english_level.test.ts @@ -0,0 +1,66 @@ +import { errors } from "../../../../utility"; +import { getEnglishLevel, readFile } from "../../../../routes/form"; +import form_keys from "../../../../routes/form_keys.json"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("english level question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/english_level_files", + "englishLevelQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEnglishLevel(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("English level options absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/english_level_files", + "englishLevelOptionsAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getEnglishLevel(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("English level amount of stars test", async () => { + const data = await readFile( + "../tests/routes_unit/form/english_level_files", + "englishLevelStars.json" + ); + expect(data).not.toBeNull(); + + await expect(getEnglishLevel(data as Form)).resolves.toStrictEqual(5); + + data?.data.fields.map((question) => { + if (question.key === form_keys.englishLevel) { + question.value = "6023fc5b-6ae2-4280-a691-37dc781044d8"; + return question; + } + return question; + }); + await expect(getEnglishLevel(data as Form)).resolves.toStrictEqual(3); + + data?.data.fields.map((question) => { + if (question.key === form_keys.englishLevel) { + question.value = "eeba838b-5a34-4c92-a8ca-4cab70d19f93"; + return question; + } + return question; + }); + await expect(getEnglishLevel(data as Form)).resolves.toStrictEqual(2); + + data?.data.fields.map((question) => { + if (question.key === form_keys.englishLevel) { + question.value = "18419bd9-82b4-40f8-980a-10ce9a022db3"; + return question; + } + return question; + }); + await expect(getEnglishLevel(data as Form)).resolves.toStrictEqual(1); +}); diff --git a/backend/tests/routes_unit/form/filter_options.test.ts b/backend/tests/routes_unit/form/filter_options.test.ts new file mode 100644 index 00000000..cadb61f3 --- /dev/null +++ b/backend/tests/routes_unit/form/filter_options.test.ts @@ -0,0 +1,41 @@ +import { readDataTestForms } from "./filter_question.test"; +import * as config from "../../../routes/form_keys.json"; +import * as form_router from "../../../routes/form"; + +describe.each([ + config.liveInBelgium, + config.volunteerInfo, + config.workInJuly, + config.nickname, + config.gender, + config.addPronouns, + config.preferredPronouns, + config.mostFluentLanguage, + config.englishLevel, + config.edus, + config.eduLevel, + config.appliedRole, + config.alumni, + config.studentCoach, +])("Options present", (key) => { + if (typeof key === "string") { + readDataTestForms().forEach((form) => { + it(`The options of the question with key ${key} are present`, () => { + const question = form_router.filterQuestion(form, key); + if (question.data !== null) { + const option = form_router.filterChosenOption( + question.data + ); + if (question.data.value === null) { + expect(option.data).toBe(null); + } else { + if (option.data !== null) { + expect(option.data).toHaveProperty("id"); + expect(option.data).toHaveProperty("text"); + } + } + } + }); + }); + } +}); diff --git a/backend/tests/routes_unit/form/filter_question.test.ts b/backend/tests/routes_unit/form/filter_question.test.ts new file mode 100644 index 00000000..b66de8c3 --- /dev/null +++ b/backend/tests/routes_unit/form/filter_question.test.ts @@ -0,0 +1,30 @@ +import * as T from "../../../types"; +import * as fs from "fs"; +import * as path from "path"; +import * as form_router from "../../../routes/form"; +import * as form_keys from "../../../routes/form_keys.json"; + +export function readDataTestForms(): T.Requests.Form[] { + return Object.values( + fs.readdirSync(path.join(__dirname, "/../../../../testforms")) + ) + .filter((filename) => filename.includes("testform")) + .map((filename) => { + const readFile = (path: string) => fs.readFileSync(path, "utf8"); + const fileData = readFile( + path.join(__dirname, `/../../../../testforms/${filename}`) + ); + return JSON.parse(fileData); + }); +} + +describe.each(Object.values(form_keys))("Questions present", (key) => { + if (typeof key === "string") { + readDataTestForms().forEach((form) => { + it(`Question with key ${key} is present`, () => { + const res = form_router.filterQuestion(form, key); + expect(res.data).not.toBe(null); + }); + }); + } +}); diff --git a/backend/tests/routes_unit/form/fun_fact_files/funFactQuestionAbsent.json b/backend/tests/routes_unit/form/fun_fact_files/funFactQuestionAbsent.json new file mode 100644 index 00000000..cea06926 --- /dev/null +++ b/backend/tests/routes_unit/form/fun_fact_files/funFactQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/fun_fact_files/fun_fact.test.ts b/backend/tests/routes_unit/form/fun_fact_files/fun_fact.test.ts new file mode 100644 index 00000000..d459c8c2 --- /dev/null +++ b/backend/tests/routes_unit/form/fun_fact_files/fun_fact.test.ts @@ -0,0 +1,16 @@ +import { errors } from "../../../../utility"; +import { getFunFact, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Fun fact question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/fun_fact_files", + "funFactQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getFunFact(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/gender_files/gender.test.ts b/backend/tests/routes_unit/form/gender_files/gender.test.ts new file mode 100644 index 00000000..b022f7f2 --- /dev/null +++ b/backend/tests/routes_unit/form/gender_files/gender.test.ts @@ -0,0 +1,28 @@ +import { errors } from "../../../../utility"; +import { getGender, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("gender question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/gender_files", + "genderQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getGender(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Gender options fail", async () => { + const data = await readFile( + "../tests/routes_unit/form/gender_files", + "genderFailChosenOption.json" + ); + expect(data).not.toBeNull(); + + await expect(getGender(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/gender_files/genderFailChosenOption.json b/backend/tests/routes_unit/form/gender_files/genderFailChosenOption.json new file mode 100644 index 00000000..2b7446c8 --- /dev/null +++ b/backend/tests/routes_unit/form/gender_files/genderFailChosenOption.json @@ -0,0 +1,706 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743" + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/gender_files/genderQuestionAbsent.json b/backend/tests/routes_unit/form/gender_files/genderQuestionAbsent.json new file mode 100644 index 00000000..de317708 --- /dev/null +++ b/backend/tests/routes_unit/form/gender_files/genderQuestionAbsent.json @@ -0,0 +1,700 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/json_to_roles_files/form.json b/backend/tests/routes_unit/form/json_to_roles_files/form.json new file mode 100644 index 00000000..eed60190 --- /dev/null +++ b/backend/tests/routes_unit/form/json_to_roles_files/form.json @@ -0,0 +1,700 @@ +{ + "eventId": "a8483798-b4cc-4e3b-88ec-870136db3f1b", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-14T19:01:22.092Z", + "data": { + "responseId": "mZWKaA", + "submissionId": "mZWKaA", + "respondentId": "mZR79a", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-14T19:01:21.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "A" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "B" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "https://www.youtube.com/watch?v=o-YBDTqX_ZU&ab_channel=MusRest" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "1@test.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "TEST" + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": "Esports" + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "25c435fd-f20a-4e70-bafd-0563089e28ec" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 7 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "1st" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "KU Leuven" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": "Gamer" + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Gaming" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/json_to_roles_files/json_to_roles.test.ts b/backend/tests/routes_unit/form/json_to_roles_files/json_to_roles.test.ts new file mode 100644 index 00000000..f79f0b85 --- /dev/null +++ b/backend/tests/routes_unit/form/json_to_roles_files/json_to_roles.test.ts @@ -0,0 +1,17 @@ +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +import * as form_router from "../../../../routes/form"; + +test("Parse the form to the applied roles", async () => { + const dataForm = await form_router.readFile( + "../tests/routes_unit/form/json_to_roles_files", + "form.json" + ); + + await expect( + form_router.jsonToRoles(dataForm as Form) + ).resolves.toStrictEqual({ + roles: ["Front-end developer", "Back-end developer"], + }); +}); diff --git a/backend/tests/routes_unit/form/lastname_files/lastname.test.ts b/backend/tests/routes_unit/form/lastname_files/lastname.test.ts new file mode 100644 index 00000000..6819a166 --- /dev/null +++ b/backend/tests/routes_unit/form/lastname_files/lastname.test.ts @@ -0,0 +1,17 @@ +import { errors } from "../../../../utility"; + +import { getLastName, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Lastname question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/lastname_files", + "lastnameQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getLastName(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/lastname_files/lastnameQuestionAbsent.json b/backend/tests/routes_unit/form/lastname_files/lastnameQuestionAbsent.json new file mode 100644 index 00000000..89e7c4fa --- /dev/null +++ b/backend/tests/routes_unit/form/lastname_files/lastnameQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageNotOther.json b/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageNotOther.json new file mode 100644 index 00000000..f3dbfa18 --- /dev/null +++ b/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageNotOther.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageOptionsAbsent.json b/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageOptionsAbsent.json new file mode 100644 index 00000000..179a0523 --- /dev/null +++ b/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageOptionsAbsent.json @@ -0,0 +1,702 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd" + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageQuestionAbsent.json b/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageQuestionAbsent.json new file mode 100644 index 00000000..016041e4 --- /dev/null +++ b/backend/tests/routes_unit/form/most_fluent_language_files/mostFluentLanguageQuestionAbsent.json @@ -0,0 +1,696 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/most_fluent_language_files/most_fluent_language.test.ts b/backend/tests/routes_unit/form/most_fluent_language_files/most_fluent_language.test.ts new file mode 100644 index 00000000..10db3828 --- /dev/null +++ b/backend/tests/routes_unit/form/most_fluent_language_files/most_fluent_language.test.ts @@ -0,0 +1,64 @@ +import { errors } from "../../../../utility"; +import { getMostFluentLanguage, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Most fluent language question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/most_fluent_language_files", + "mostFluentLanguageQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getMostFluentLanguage(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Most fluent language options absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/most_fluent_language_files", + "mostFluentLanguageOptionsAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getMostFluentLanguage(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Most fluent language other option question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/most_fluent_language_files", + "otherQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getMostFluentLanguage(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Most fluent language other option question not absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/most_fluent_language_files", + "otherQuestionNotAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getMostFluentLanguage(data as Form)).resolves.toStrictEqual( + "Danish" + ); +}); + +test("Most fluent language value is not other", async () => { + const data = await readFile( + "../tests/routes_unit/form/most_fluent_language_files", + "mostFluentLanguageNotOther.json" + ); + expect(data).not.toBeNull(); + + await expect(getMostFluentLanguage(data as Form)).resolves.toStrictEqual( + "Dutch" + ); +}); diff --git a/backend/tests/routes_unit/form/most_fluent_language_files/otherQuestionAbsent.json b/backend/tests/routes_unit/form/most_fluent_language_files/otherQuestionAbsent.json new file mode 100644 index 00000000..1a683846 --- /dev/null +++ b/backend/tests/routes_unit/form/most_fluent_language_files/otherQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/most_fluent_language_files/otherQuestionNotAbsent.json b/backend/tests/routes_unit/form/most_fluent_language_files/otherQuestionNotAbsent.json new file mode 100644 index 00000000..f537cd16 --- /dev/null +++ b/backend/tests/routes_unit/form/most_fluent_language_files/otherQuestionNotAbsent.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": "Danish" + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/motivation_files/motivation.test.ts b/backend/tests/routes_unit/form/motivation_files/motivation.test.ts new file mode 100644 index 00000000..86030f9c --- /dev/null +++ b/backend/tests/routes_unit/form/motivation_files/motivation.test.ts @@ -0,0 +1,72 @@ +import { errors } from "../../../../utility"; + +import { getMotivation, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("The value of the motivation link field is not empty", async () => { + const data = await readFile( + "../tests/routes_unit/form/motivation_files", + "motivationLinkValueNotEmpty.json" + ); + expect(data).not.toBeNull(); + + await expect(getMotivation(data as Form)).resolves.toStrictEqual({ + data: [ + "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + ], + types: ["MOTIVATION_URL"], + }); +}); + +test("The motivation link question is absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/motivation_files", + "motivationLinkQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getMotivation(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("The url field in the motivation upload question is undefined", async () => { + const data = await readFile( + "../tests/routes_unit/form/motivation_files", + "motivationUrlNotDefined.json" + ); + expect(data).not.toBeNull(); + + await expect(getMotivation(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("The value of the motivation upload field is valid", async () => { + const data = await readFile( + "../tests/routes_unit/form/motivation_files", + "motivationUploadValueValid.json" + ); + expect(data).not.toBeNull(); + + await expect(getMotivation(data as Form)).resolves.toStrictEqual({ + data: [ + "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + ], + types: ["MOTIVATION_URL"], + }); +}); + +test("The value of the motivation string field is valid", async () => { + const data = await readFile( + "../tests/routes_unit/form/motivation_files", + "motivationStringFieldValid.json" + ); + expect(data).not.toBeNull(); + + await expect(getMotivation(data as Form)).resolves.toStrictEqual({ + data: ["I am motivated"], + types: ["MOTIVATION_STRING"], + }); +}); diff --git a/backend/tests/routes_unit/form/motivation_files/motivationLinkQuestionAbsent.json b/backend/tests/routes_unit/form/motivation_files/motivationLinkQuestionAbsent.json new file mode 100644 index 00000000..1f6ce6dd --- /dev/null +++ b/backend/tests/routes_unit/form/motivation_files/motivationLinkQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/motivation_files/motivationLinkValueNotEmpty.json b/backend/tests/routes_unit/form/motivation_files/motivationLinkValueNotEmpty.json new file mode 100644 index 00000000..aec01309 --- /dev/null +++ b/backend/tests/routes_unit/form/motivation_files/motivationLinkValueNotEmpty.json @@ -0,0 +1,700 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt" + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/motivation_files/motivationStringFieldValid.json b/backend/tests/routes_unit/form/motivation_files/motivationStringFieldValid.json new file mode 100644 index 00000000..c8165846 --- /dev/null +++ b/backend/tests/routes_unit/form/motivation_files/motivationStringFieldValid.json @@ -0,0 +1,700 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": "I am motivated" + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/motivation_files/motivationUploadValueValid.json b/backend/tests/routes_unit/form/motivation_files/motivationUploadValueValid.json new file mode 100644 index 00000000..8b494153 --- /dev/null +++ b/backend/tests/routes_unit/form/motivation_files/motivationUploadValueValid.json @@ -0,0 +1,708 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/motivation_files/motivationUrlNotDefined.json b/backend/tests/routes_unit/form/motivation_files/motivationUrlNotDefined.json new file mode 100644 index 00000000..e3dacc51 --- /dev/null +++ b/backend/tests/routes_unit/form/motivation_files/motivationUrlNotDefined.json @@ -0,0 +1,723 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/nickname_files/nickname.test.ts b/backend/tests/routes_unit/form/nickname_files/nickname.test.ts new file mode 100644 index 00000000..a8a51205 --- /dev/null +++ b/backend/tests/routes_unit/form/nickname_files/nickname.test.ts @@ -0,0 +1,38 @@ +import { errors } from "../../../../utility"; +import { getNickname, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Nickname question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/nickname_files", + "nicknameQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getNickname(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Nickname text field value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/nickname_files", + "nicknameFieldValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getNickname(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Nickname text field value is not null", async () => { + const data = await readFile( + "../tests/routes_unit/form/nickname_files", + "nicknameFieldValueNotNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getNickname(data as Form)).resolves.toStrictEqual("Luc"); +}); diff --git a/backend/tests/routes_unit/form/nickname_files/nicknameFieldValueNotNull.json b/backend/tests/routes_unit/form/nickname_files/nicknameFieldValueNotNull.json new file mode 100644 index 00000000..f3dbfa18 --- /dev/null +++ b/backend/tests/routes_unit/form/nickname_files/nicknameFieldValueNotNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/nickname_files/nicknameFieldValueNull.json b/backend/tests/routes_unit/form/nickname_files/nicknameFieldValueNull.json new file mode 100644 index 00000000..005b3d21 --- /dev/null +++ b/backend/tests/routes_unit/form/nickname_files/nicknameFieldValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/nickname_files/nicknameQuestionAbsent.json b/backend/tests/routes_unit/form/nickname_files/nicknameQuestionAbsent.json new file mode 100644 index 00000000..5395cb0e --- /dev/null +++ b/backend/tests/routes_unit/form/nickname_files/nicknameQuestionAbsent.json @@ -0,0 +1,708 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/parse_form_request.test.ts b/backend/tests/routes_unit/form/parse_form_request.test.ts new file mode 100644 index 00000000..906bcd15 --- /dev/null +++ b/backend/tests/routes_unit/form/parse_form_request.test.ts @@ -0,0 +1,51 @@ +import { readDataTestForms } from "./filter_question.test"; +import express from "express"; +import { getMockReq } from "@jest-mock/express"; +import * as Rq from "../../../request"; +import { errors } from "../../../utility"; + +test("Can parse form request", () => { + const resultList: Promise[] = []; + const req: express.Request = getMockReq(); + + req.body = {}; + resultList.push( + expect(Rq.parseFormRequest(req)).rejects.toBe( + errors.cookArgumentError() + ) + ); + + const req2: express.Request = getMockReq(); + req2.body = { data: {} }; + resultList.push( + expect(Rq.parseFormRequest(req2)).rejects.toBe( + errors.cookArgumentError() + ) + ); + + const req3: express.Request = getMockReq(); + req3.body = { data: { fields: [{ value: "value" }] } }; + resultList.push( + expect(Rq.parseFormRequest(req3)).rejects.toBe( + errors.cookArgumentError() + ) + ); + + readDataTestForms().forEach((data) => { + const req4: express.Request = getMockReq(); + req4.body = { ...data }; + const v1 = expect(Rq.parseFormRequest(req4)).resolves.toHaveProperty( + "data", + data.data + ); + const v2 = expect(Rq.parseFormRequest(req4)).resolves.toHaveProperty( + "createdAt", + data.createdAt + ); + + resultList.push(v1); + resultList.push(v2); + }); + + return Promise.all(resultList); +}); diff --git a/backend/tests/routes_unit/form/phone_number_files/phoneNumberQuestionAbsent.json b/backend/tests/routes_unit/form/phone_number_files/phoneNumberQuestionAbsent.json new file mode 100644 index 00000000..a26544a1 --- /dev/null +++ b/backend/tests/routes_unit/form/phone_number_files/phoneNumberQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/phone_number_files/phone_number.test.ts b/backend/tests/routes_unit/form/phone_number_files/phone_number.test.ts new file mode 100644 index 00000000..aaf5cba0 --- /dev/null +++ b/backend/tests/routes_unit/form/phone_number_files/phone_number.test.ts @@ -0,0 +1,16 @@ +import { errors } from "../../../../utility"; +import { getPhoneNumber, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Phone number question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/phone_number_files", + "phoneNumberQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getPhoneNumber(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/form/portfolio_files/portfolio.test.ts b/backend/tests/routes_unit/form/portfolio_files/portfolio.test.ts new file mode 100644 index 00000000..b28a044f --- /dev/null +++ b/backend/tests/routes_unit/form/portfolio_files/portfolio.test.ts @@ -0,0 +1,59 @@ +import { errors } from "../../../../utility"; + +import { getPortfolio, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("The portfolio link question is absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/portfolio_files", + "portfolioLinkQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getPortfolio(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("The value of the portfolio link question is not empty", async () => { + const data = await readFile( + "../tests/routes_unit/form/portfolio_files", + "portfolioLinkValueNotEmpty.json" + ); + expect(data).not.toBeNull(); + + await expect(getPortfolio(data as Form)).resolves.toStrictEqual({ + data: [ + "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + ], + types: ["PORTFOLIO_URL"], + }); +}); + +test("The url field in the portfolio upload question is undefined", async () => { + const data = await readFile( + "../tests/routes_unit/form/portfolio_files", + "portfolioUrlNotDefined.json" + ); + expect(data).not.toBeNull(); + + await expect(getPortfolio(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("The value of the portfolio upload field is valid", async () => { + const data = await readFile( + "../tests/routes_unit/form/portfolio_files", + "portfolioUploadValueValid.json" + ); + expect(data).not.toBeNull(); + + await expect(getPortfolio(data as Form)).resolves.toStrictEqual({ + data: [ + "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + ], + types: ["PORTFOLIO_URL"], + }); +}); diff --git a/backend/tests/routes_unit/form/portfolio_files/portfolioLinkQuestionAbsent.json b/backend/tests/routes_unit/form/portfolio_files/portfolioLinkQuestionAbsent.json new file mode 100644 index 00000000..cc91226a --- /dev/null +++ b/backend/tests/routes_unit/form/portfolio_files/portfolioLinkQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/portfolio_files/portfolioLinkValueNotEmpty.json b/backend/tests/routes_unit/form/portfolio_files/portfolioLinkValueNotEmpty.json new file mode 100644 index 00000000..a806ebf1 --- /dev/null +++ b/backend/tests/routes_unit/form/portfolio_files/portfolioLinkValueNotEmpty.json @@ -0,0 +1,700 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt" + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/portfolio_files/portfolioUploadValueValid.json b/backend/tests/routes_unit/form/portfolio_files/portfolioUploadValueValid.json new file mode 100644 index 00000000..695fa107 --- /dev/null +++ b/backend/tests/routes_unit/form/portfolio_files/portfolioUploadValueValid.json @@ -0,0 +1,708 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/portfolio_files/portfolioUrlNotDefined.json b/backend/tests/routes_unit/form/portfolio_files/portfolioUrlNotDefined.json new file mode 100644 index 00000000..c9aa8e87 --- /dev/null +++ b/backend/tests/routes_unit/form/portfolio_files/portfolioUrlNotDefined.json @@ -0,0 +1,707 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": null + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/pronouns_files/enterPronounsValueNotNull.json b/backend/tests/routes_unit/form/pronouns_files/enterPronounsValueNotNull.json new file mode 100644 index 00000000..3de96c95 --- /dev/null +++ b/backend/tests/routes_unit/form/pronouns_files/enterPronounsValueNotNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": "by firstname" + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/pronouns_files/enterPronounsValueNull.json b/backend/tests/routes_unit/form/pronouns_files/enterPronounsValueNull.json new file mode 100644 index 00000000..54b7eebb --- /dev/null +++ b/backend/tests/routes_unit/form/pronouns_files/enterPronounsValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/pronouns_files/preferredPronounsNotOtherOption.json b/backend/tests/routes_unit/form/pronouns_files/preferredPronounsNotOtherOption.json new file mode 100644 index 00000000..f3dbfa18 --- /dev/null +++ b/backend/tests/routes_unit/form/pronouns_files/preferredPronounsNotOtherOption.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/pronouns_files/preferredPronounsValueNull.json b/backend/tests/routes_unit/form/pronouns_files/preferredPronounsValueNull.json new file mode 100644 index 00000000..35f35571 --- /dev/null +++ b/backend/tests/routes_unit/form/pronouns_files/preferredPronounsValueNull.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": null, + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/pronouns_files/pronouns.test.ts b/backend/tests/routes_unit/form/pronouns_files/pronouns.test.ts new file mode 100644 index 00000000..4eed8a7f --- /dev/null +++ b/backend/tests/routes_unit/form/pronouns_files/pronouns.test.ts @@ -0,0 +1,72 @@ +import { errors } from "../../../../utility"; +import { getPronouns, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Pronouns question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/pronouns_files", + "pronounsQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getPronouns(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Pronouns options absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/pronouns_files", + "pronounsOptionsAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getPronouns(data as Form)).resolves.toBeNull(); +}); + +test("Preferred pronouns value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/pronouns_files", + "preferredPronounsValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getPronouns(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("The chosen option is not the other option", async () => { + const data = await readFile( + "../tests/routes_unit/form/pronouns_files", + "preferredPronounsNotOtherOption.json" + ); + expect(data).not.toBeNull(); + + await expect(getPronouns(data as Form)).resolves.toStrictEqual( + "by call name" + ); +}); + +test("The enter pronouns field value is null", async () => { + const data = await readFile( + "../tests/routes_unit/form/pronouns_files", + "enterPronounsValueNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getPronouns(data as Form)).resolves.toBeNull(); +}); + +test("The enter pronouns field value is not null", async () => { + const data = await readFile( + "../tests/routes_unit/form/pronouns_files", + "enterPronounsValueNotNull.json" + ); + expect(data).not.toBeNull(); + + await expect(getPronouns(data as Form)).resolves.toStrictEqual( + "by firstname" + ); +}); diff --git a/backend/tests/routes_unit/form/pronouns_files/pronounsOptionsAbsent.json b/backend/tests/routes_unit/form/pronouns_files/pronounsOptionsAbsent.json new file mode 100644 index 00000000..db9d8ad3 --- /dev/null +++ b/backend/tests/routes_unit/form/pronouns_files/pronounsOptionsAbsent.json @@ -0,0 +1,714 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230" + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/pronouns_files/pronounsQuestionAbsent.json b/backend/tests/routes_unit/form/pronouns_files/pronounsQuestionAbsent.json new file mode 100644 index 00000000..59160221 --- /dev/null +++ b/backend/tests/routes_unit/form/pronouns_files/pronounsQuestionAbsent.json @@ -0,0 +1,708 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/responsibilities_files/responsibilities.test.ts b/backend/tests/routes_unit/form/responsibilities_files/responsibilities.test.ts new file mode 100644 index 00000000..187ac0ad --- /dev/null +++ b/backend/tests/routes_unit/form/responsibilities_files/responsibilities.test.ts @@ -0,0 +1,28 @@ +import { errors } from "../../../../utility"; +import { getResponsibilities, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Responsibilities question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/responsibilities_files", + "responsibilitiesQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getResponsibilities(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Responsibilities value undefined", async () => { + const data = await readFile( + "../tests/routes_unit/form/responsibilities_files", + "responsibilitiesValueUndefined.json" + ); + expect(data).not.toBeNull(); + + await expect(getResponsibilities(data as Form)).resolves.toStrictEqual( + null + ); +}); diff --git a/backend/tests/routes_unit/form/responsibilities_files/responsibilitiesQuestionAbsent.json b/backend/tests/routes_unit/form/responsibilities_files/responsibilitiesQuestionAbsent.json new file mode 100644 index 00000000..8f124f78 --- /dev/null +++ b/backend/tests/routes_unit/form/responsibilities_files/responsibilitiesQuestionAbsent.json @@ -0,0 +1,718 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/responsibilities_files/responsibilitiesValueUndefined.json b/backend/tests/routes_unit/form/responsibilities_files/responsibilitiesValueUndefined.json new file mode 100644 index 00000000..51afaf72 --- /dev/null +++ b/backend/tests/routes_unit/form/responsibilities_files/responsibilitiesValueUndefined.json @@ -0,0 +1,723 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA" + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/student_coach_files/studentCoachNotParticipatedYet.json b/backend/tests/routes_unit/form/student_coach_files/studentCoachNotParticipatedYet.json new file mode 100644 index 00000000..2919111c --- /dev/null +++ b/backend/tests/routes_unit/form/student_coach_files/studentCoachNotParticipatedYet.json @@ -0,0 +1,724 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "ffa7874f-52db-4058-93a1-8a015376f256", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/student_coach_files/studentCoachOptionsAbsent.json b/backend/tests/routes_unit/form/student_coach_files/studentCoachOptionsAbsent.json new file mode 100644 index 00000000..c0ff2c14 --- /dev/null +++ b/backend/tests/routes_unit/form/student_coach_files/studentCoachOptionsAbsent.json @@ -0,0 +1,714 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705" + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/student_coach_files/studentCoachQuestionAbsent.json b/backend/tests/routes_unit/form/student_coach_files/studentCoachQuestionAbsent.json new file mode 100644 index 00000000..d7afd5a0 --- /dev/null +++ b/backend/tests/routes_unit/form/student_coach_files/studentCoachQuestionAbsent.json @@ -0,0 +1,708 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "options": [ + { + "id": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf", + "text": "Yes, I can work with a student employment agreement in Belgium" + }, + { + "id": "f41e1bef-8a6c-4f9f-b369-cd388aacd9f9", + "text": "Yes, I can work as a volunteer in Belgium" + }, + { + "id": "230a7690-7e05-43d5-97a4-58c0e37142dc", + "text": "No – but I would like to join this experience for free" + }, + { + "id": "9a065686-5d60-423f-a343-db8ae9066028", + "text": "No, I won’t be able to work as a student, as a volunteer or for free." + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/student_coach_files/student_coach.test.ts b/backend/tests/routes_unit/form/student_coach_files/student_coach.test.ts new file mode 100644 index 00000000..f0e0d295 --- /dev/null +++ b/backend/tests/routes_unit/form/student_coach_files/student_coach.test.ts @@ -0,0 +1,38 @@ +import { errors } from "../../../../utility"; +import { isStudentCoach, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Student coach question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/student_coach_files", + "studentCoachQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(isStudentCoach(data as Form, true)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Student coach options absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/student_coach_files", + "studentCoachOptionsAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(isStudentCoach(data as Form, true)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Student coach value is No", async () => { + const data = await readFile( + "../tests/routes_unit/form/student_coach_files", + "studentCoachNotParticipatedYet.json" + ); + expect(data).not.toBeNull(); + + await expect(isStudentCoach(data as Form, false)).resolves.toBeNull(); +}); diff --git a/backend/tests/routes_unit/form/volunteer_info_files/volunteerInfoOptionsAbsent.json b/backend/tests/routes_unit/form/volunteer_info_files/volunteerInfoOptionsAbsent.json new file mode 100644 index 00000000..c6c36aa0 --- /dev/null +++ b/backend/tests/routes_unit/form/volunteer_info_files/volunteerInfoOptionsAbsent.json @@ -0,0 +1,706 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_wLpAAJ", + "label": "Are you able to work 128 hours with a student employment agreement, or as a volunteer?*", + "type": "MULTIPLE_CHOICE", + "value": "46db63af-daaa-42ec-a755-8ff5c6d2b1bf" + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/volunteer_info_files/volunteerInfoQuestionAbsent.json b/backend/tests/routes_unit/form/volunteer_info_files/volunteerInfoQuestionAbsent.json new file mode 100644 index 00000000..1de5610d --- /dev/null +++ b/backend/tests/routes_unit/form/volunteer_info_files/volunteerInfoQuestionAbsent.json @@ -0,0 +1,700 @@ +{ + "eventId": "fd1a7892-7e9b-4db5-9eba-1de1e4000337", + "eventType": "FORM_RESPONSE", + "createdAt": "2022-04-28T20:03:48.775Z", + "data": { + "responseId": "wA5WMe", + "submissionId": "wA5WMe", + "respondentId": "3j9JVY", + "formId": "wMoDMm", + "formName": "(UGent) #osoc22 student application form", + "createdAt": "2022-04-28T20:03:48.000Z", + "fields": [ + { + "key": "question_mK177D", + "label": "Will you live in Belgium in July 2022?*", + "type": "MULTIPLE_CHOICE", + "value": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "options": [ + { + "id": "343f74a1-7b3d-481e-94f1-cfd613d78f00", + "text": "Yes" + }, + { + "id": "2cf437cc-fee4-496b-8e46-f6c037dca583", + "text": "No" + } + ] + }, + { + "key": "question_npOjjP", + "label": "Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)?*", + "type": "MULTIPLE_CHOICE", + "value": "115ad290-a86e-42f5-939e-8276ff41e749", + "options": [ + { + "id": "115ad290-a86e-42f5-939e-8276ff41e749", + "text": "Yes" + }, + { + "id": "7e42e1a5-a15a-4866-b92a-5fd8041a5cc4", + "text": "No, I wouldn't be able to work for the majority of days." + } + ] + }, + { + "key": "question_31VZZb", + "label": "Are there any responsibilities you might have which could hinder you during the day?", + "type": "TEXTAREA", + "value": "I'm in a wheelchair." + }, + { + "key": "question_wMRkk8", + "label": "Birth name", + "type": "INPUT_TEXT", + "value": "Lucas" + }, + { + "key": "question_mJzaaX", + "label": "Last name", + "type": "INPUT_TEXT", + "value": "Chen" + }, + { + "key": "question_wgGyyJ", + "label": "Would you like to be called by a different name than your birth name?", + "type": "MULTIPLE_CHOICE", + "value": "35e07206-f052-4826-8965-515ed783a43e", + "options": [ + { + "id": "35e07206-f052-4826-8965-515ed783a43e", + "text": "Yes" + }, + { + "id": "e3558697-3a38-4137-b699-1fb8ec93e9ab", + "text": "No" + } + ] + }, + { + "key": "question_3yYKKd", + "label": "How would you like to be called?", + "type": "INPUT_TEXT", + "value": "Luc" + }, + { + "key": "question_3X0VVz", + "label": "What is your gender?", + "type": "MULTIPLE_CHOICE", + "value": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "options": [ + { + "id": "d664cd5f-121f-421c-8f2c-e1b8b6505899", + "text": "Female" + }, + { + "id": "2bcf2809-3efe-407d-87c1-dabcf3db0743", + "text": "Male" + }, + { + "id": "afd31775-f165-41d0-9dd2-45dd4ae1c90a", + "text": "Transgender" + }, + { + "id": "fc2cc0be-6688-4ab8-9567-36bedbe829b2", + "text": "Rather not say" + } + ] + }, + { + "key": "question_w8xvvr", + "label": "Would you like to add your pronouns?", + "type": "MULTIPLE_CHOICE", + "value": "8b2065a1-09f1-46dc-a03e-138a20160230", + "options": [ + { + "id": "8b2065a1-09f1-46dc-a03e-138a20160230", + "text": "Yes" + }, + { + "id": "e08c0951-9ea4-4781-b5e4-a5252b91855f", + "text": "No" + } + ] + }, + { + "key": "question_n0O22A", + "label": "Which pronouns do you prefer?", + "type": "MULTIPLE_CHOICE", + "value": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "options": [ + { + "id": "97e74546-7f92-422c-b2be-ffaf7ef3f50b", + "text": "she/her/hers" + }, + { + "id": "a8a3c71b-2d52-4319-9399-e13eeffb7e99", + "text": "he/him/his" + }, + { + "id": "57489d99-aa62-4f9a-a9b9-5975570ea7d7", + "text": "they/them/theirs" + }, + { + "id": "071f603c-e1f6-4212-bc2d-57a173a076b6", + "text": "ze/hir/hir " + }, + { + "id": "4e0d7394-23b3-4469-ad2d-2b6482186f8c", + "text": "by firstname" + }, + { + "id": "a5c6726f-661e-43e1-b913-c33683f20ddd", + "text": "by call name" + }, + { + "id": "c15e9f19-2997-4882-b7ec-1f3fd9c70af0", + "text": "other" + } + ] + }, + { + "key": "question_wzYppg", + "label": "Enter your pronouns", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w5x66Q", + "label": "What language are you most fluent in?", + "type": "MULTIPLE_CHOICE", + "value": "66165a2c-404a-4def-b925-846769a123bd", + "options": [ + { + "id": "66165a2c-404a-4def-b925-846769a123bd", + "text": "Dutch" + }, + { + "id": "86bb74b6-5dd8-4ce0-b28a-962604d2c630", + "text": "English" + }, + { + "id": "551bd941-9c3c-4805-89c0-22ae46ac89d0", + "text": "French" + }, + { + "id": "1ed59443-b164-4ddf-85ff-c603cd4edaf1", + "text": "German" + }, + { + "id": "3594c098-46fd-4bf9-98b3-c11e568c3403", + "text": "Other" + } + ] + }, + { + "key": "question_wddLLV", + "label": "What language are you most fluent in?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mYaEEv", + "label": "How would you rate your English?", + "type": "MULTIPLE_CHOICE", + "value": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "options": [ + { + "id": "18419bd9-82b4-40f8-980a-10ce9a022db3", + "text": "★ I can understand your form, but it is hard for me to reply." + }, + { + "id": "eeba838b-5a34-4c92-a8ca-4cab70d19f93", + "text": "★★ I can have simple conversations." + }, + { + "id": "6023fc5b-6ae2-4280-a691-37dc781044d8", + "text": "★★★ I can express myself, understand people and get a point across." + }, + { + "id": "4bab946f-ff92-4e32-abd7-ed0c9113cdbf", + "text": "★★★★ I can have extensive and complicated conversations." + }, + { + "id": "1f4fa6d9-b2ba-42a7-9f82-5b1be7598d3e", + "text": "★★★★★ I am fluent." + } + ] + }, + { + "key": "question_mDzrrE", + "label": "Phone number", + "type": "INPUT_PHONE_NUMBER", + "value": "0428179834" + }, + { + "key": "question_3lrooX", + "label": "Your email address\n", + "type": "INPUT_EMAIL", + "value": "lucas.chen@student.com" + }, + { + "key": "question_mRPXXQ", + "label": "Upload your CV – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "mZo0pA", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/366ea459-5f04-4fa0-81e8-f39a4bcd2a25/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_woGrrN", + "label": "Or link to your CV", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_nGlNNO", + "label": "Upload your portfolio – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3NDkeN", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/b1a201e0-9d51-4cba-811b-a6c62c0ba098/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_mOGppM", + "label": "Or link to your portfolio / GitHub", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_mVJRR6", + "label": "Upload your motivation – size limit 10MB", + "type": "FILE_UPLOAD", + "value": [ + { + "id": "3qa628", + "name": "attachment.txt", + "url": "https://storage.googleapis.com/tally-response-assets/repXzN/acddeba6-6022-4eed-88cc-7e6b632dcf55/attachment.txt", + "mimeType": "text/plain", + "size": 4 + } + ] + }, + { + "key": "question_nPOMMx", + "label": "Or link to your motivation", + "type": "INPUT_LINK", + "value": null + }, + { + "key": "question_3EWjj2", + "label": "Or write about your motivation", + "type": "TEXTAREA", + "value": null + }, + { + "key": "question_nrPNNX", + "label": "Add a fun fact about yourself", + "type": "TEXTAREA", + "value": "I am funny." + }, + { + "key": "question_w4rWW5", + "label": "What do/did you study?", + "type": "CHECKBOXES", + "value": [ + "63669061-f3e1-4b97-addc-f8b37a3989f4", + "ef021761-9972-46d6-960a-0236ba723963" + ], + "options": [ + { + "id": "63669061-f3e1-4b97-addc-f8b37a3989f4", + "text": "Backend development" + }, + { + "id": "816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "text": "Business management" + }, + { + "id": "dfedd70f-5780-42b4-bc74-85d3c4e69225", + "text": "Communication Sciences" + }, + { + "id": "de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "text": "Computer Sciences" + }, + { + "id": "7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "text": "Design" + }, + { + "id": "ef021761-9972-46d6-960a-0236ba723963", + "text": "Frontend development" + }, + { + "id": "bdefa065-f120-488b-bd01-244c5a59f20e", + "text": "Marketing" + }, + { + "id": "c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "text": "Photography" + }, + { + "id": "e9964b65-12b7-4179-91bc-d63f5f02aee9", + "text": "Videography" + }, + { + "id": "dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "text": "Other" + } + ] + }, + { + "key": "question_w4rWW5_63669061-f3e1-4b97-addc-f8b37a3989f4", + "label": "What do/did you study? (Backend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_816606cb-4f87-4632-9c27-7f09e1c0d0f4", + "label": "What do/did you study? (Business management)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dfedd70f-5780-42b4-bc74-85d3c4e69225", + "label": "What do/did you study? (Communication Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_de2a0d9b-2cc1-472f-ad76-954677a8afb1", + "label": "What do/did you study? (Computer Sciences)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_7f51c707-09f4-48bb-b6ea-1f90f5a7dee2", + "label": "What do/did you study? (Design)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_ef021761-9972-46d6-960a-0236ba723963", + "label": "What do/did you study? (Frontend development)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w4rWW5_bdefa065-f120-488b-bd01-244c5a59f20e", + "label": "What do/did you study? (Marketing)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_c2c15641-dee6-4712-8fdf-0448d2dcaed1", + "label": "What do/did you study? (Photography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_e9964b65-12b7-4179-91bc-d63f5f02aee9", + "label": "What do/did you study? (Videography)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w4rWW5_dbb51b92-95ac-4e17-ba9b-925dd8feeb0a", + "label": "What do/did you study? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3jPdd1", + "label": "What do/did you study?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_w2PqqM", + "label": "What kind of diploma are you currently going for?", + "type": "CHECKBOXES", + "value": [ + "a27ad504-f524-4e5b-9919-2ad70c14814a" + ], + "options": [ + { + "id": "ee039478-24af-46f0-8619-d0615512c2b7", + "text": "A professional Bachelor" + }, + { + "id": "a27ad504-f524-4e5b-9919-2ad70c14814a", + "text": "An academic Bachelor" + }, + { + "id": "97dbef1b-d707-4585-b61b-45c99db6c54c", + "text": "An associate degree" + }, + { + "id": "9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "text": "A master's degree" + }, + { + "id": "25c435fd-f20a-4e70-bafd-0563089e28ec", + "text": "Doctoral degree" + }, + { + "id": "e5f9b310-6087-4c44-8422-ccee50b9378b", + "text": "No diploma, I am self taught" + }, + { + "id": "67e44797-6696-4605-b1bd-bf76859c70f9", + "text": "Other" + } + ] + }, + { + "key": "question_w2PqqM_ee039478-24af-46f0-8619-d0615512c2b7", + "label": "What kind of diploma are you currently going for? (A professional Bachelor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_a27ad504-f524-4e5b-9919-2ad70c14814a", + "label": "What kind of diploma are you currently going for? (An academic Bachelor)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_w2PqqM_97dbef1b-d707-4585-b61b-45c99db6c54c", + "label": "What kind of diploma are you currently going for? (An associate degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_9c28047c-0392-42eb-9e0f-0bd1b03a5e12", + "label": "What kind of diploma are you currently going for? (A master's degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_25c435fd-f20a-4e70-bafd-0563089e28ec", + "label": "What kind of diploma are you currently going for? (Doctoral degree)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_e5f9b310-6087-4c44-8422-ccee50b9378b", + "label": "What kind of diploma are you currently going for? (No diploma, I am self taught)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_w2PqqM_67e44797-6696-4605-b1bd-bf76859c70f9", + "label": "What kind of diploma are you currently going for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_3xYkkk", + "label": "What kind of diploma are you currently going for?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_mZ6555", + "label": "How many years does your degree take?", + "type": "INPUT_NUMBER", + "value": 5 + }, + { + "key": "question_3NW55p", + "label": "Which year of your degree are you in?", + "type": "INPUT_TEXT", + "value": "3th" + }, + { + "key": "question_3qAZZ5", + "label": "What is the name of your college or university?", + "type": "INPUT_TEXT", + "value": "UGent" + }, + { + "key": "question_wQ5221", + "label": "Which role are you applying for?", + "type": "CHECKBOXES", + "value": [ + "687908c0-7091-429c-9f99-cf9670503892" + ], + "options": [ + { + "id": "d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "text": "Front-end developer" + }, + { + "id": "687908c0-7091-429c-9f99-cf9670503892", + "text": "Back-end developer" + }, + { + "id": "def165c9-d40a-4d13-b174-98d480e1dd41", + "text": "UX / UI designer" + }, + { + "id": "fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "text": "Graphic designer" + }, + { + "id": "37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "text": "Business Modeller" + }, + { + "id": "07228f94-e28d-41f6-ac6e-ccd039921f58", + "text": "Storyteller" + }, + { + "id": "4b1c6ba6-e945-465e-9222-de02d44988ce", + "text": "Marketer" + }, + { + "id": "e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "text": "Copywriter" + }, + { + "id": "e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "text": "Video editor" + }, + { + "id": "7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "text": "Photographer" + }, + { + "id": "dede10c8-a949-463c-8ae8-73f6fab6a362", + "text": "Other" + } + ] + }, + { + "key": "question_wQ5221_d2c3e561-28bd-4de9-a7db-00cd22beb3b7", + "label": "Which role are you applying for? (Front-end developer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_687908c0-7091-429c-9f99-cf9670503892", + "label": "Which role are you applying for? (Back-end developer)", + "type": "CHECKBOXES", + "value": true + }, + { + "key": "question_wQ5221_def165c9-d40a-4d13-b174-98d480e1dd41", + "label": "Which role are you applying for? (UX / UI designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_fae1aff3-eb1c-4109-abb5-c91ed8e64cf1", + "label": "Which role are you applying for? (Graphic designer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_37c7da5d-361c-4000-b8ed-fcf8e69971f0", + "label": "Which role are you applying for? (Business Modeller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_07228f94-e28d-41f6-ac6e-ccd039921f58", + "label": "Which role are you applying for? (Storyteller)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_4b1c6ba6-e945-465e-9222-de02d44988ce", + "label": "Which role are you applying for? (Marketer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e993e2bb-6dfe-4ec3-8f36-cf940b30533e", + "label": "Which role are you applying for? (Copywriter)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_e7f54c05-e90b-4967-b9a5-7fa997abdabc", + "label": "Which role are you applying for? (Video editor)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_7418ba9a-e88b-4a4c-98e7-4f346d61024e", + "label": "Which role are you applying for? (Photographer)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_wQ5221_dede10c8-a949-463c-8ae8-73f6fab6a362", + "label": "Which role are you applying for? (Other)", + "type": "CHECKBOXES", + "value": false + }, + { + "key": "question_n9DGGX", + "label": "Which role are you applying for that is not in the list above?", + "type": "INPUT_TEXT", + "value": null + }, + { + "key": "question_meeZZQ", + "label": "Which skill would you list as your best one?", + "type": "INPUT_TEXT", + "value": "Back-end developing" + }, + { + "key": "question_nW599R", + "label": "Have you participated in osoc before?", + "type": "MULTIPLE_CHOICE", + "value": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "options": [ + { + "id": "e47f258c-dc5e-449e-bf93-5587d5b8f3ee", + "text": "No, it's my first time participating in osoc" + }, + { + "id": "127d3ef2-2929-4895-ba52-4d10bcaa1e19", + "text": "Yes, I have been part of osoc before" + } + ] + }, + { + "key": "question_waYNN2", + "label": "Would you like to be a student coach this year?", + "type": "MULTIPLE_CHOICE", + "value": "6959f608-436d-4da8-a14e-f9cedb99f705", + "options": [ + { + "id": "ffa7874f-52db-4058-93a1-8a015376f256", + "text": "No, I don't want to be a student coach" + }, + { + "id": "6959f608-436d-4da8-a14e-f9cedb99f705", + "text": "Yes, I'd like to be a student coach" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/tests/routes_unit/form/volunteer_info_files/volunteer_info.test.ts b/backend/tests/routes_unit/form/volunteer_info_files/volunteer_info.test.ts new file mode 100644 index 00000000..e7b0b2eb --- /dev/null +++ b/backend/tests/routes_unit/form/volunteer_info_files/volunteer_info.test.ts @@ -0,0 +1,28 @@ +import { errors } from "../../../../utility"; +import { getVolunteerInfo, readFile } from "../../../../routes/form"; +import { Requests } from "../../../../types"; +import Form = Requests.Form; + +test("Volunteer info question absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/volunteer_info_files", + "volunteerInfoQuestionAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getVolunteerInfo(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); + +test("Volunteer info options are absent", async () => { + const data = await readFile( + "../tests/routes_unit/form/volunteer_info_files", + "volunteerInfoOptionsAbsent.json" + ); + expect(data).not.toBeNull(); + + await expect(getVolunteerInfo(data as Form)).rejects.toBe( + errors.cookArgumentError() + ); +}); diff --git a/backend/tests/routes_unit/github.test.ts b/backend/tests/routes_unit/github.test.ts index 6df639e8..bd9f7586 100644 --- a/backend/tests/routes_unit/github.test.ts +++ b/backend/tests/routes_unit/github.test.ts @@ -43,7 +43,7 @@ beforeEach(() => { ? { github: "@my_github", person_id: 69, - firstname: "my", + name: "my", login_user: { password: null, login_user_id: 420, @@ -59,18 +59,17 @@ beforeEach(() => { ormPMock.updatePerson.mockImplementation((u) => Promise.resolve({ person_id: u.personId, - firstname: u.firstname != null ? u.firstname : "jeff", + name: u.name != null ? u.name : "jeff", email: u.email != null ? u.email : null, github: u.github != null ? u.github : "@my_acct", github_id: "784", - lastname: u.lastname != null ? u.lastname : "", + lastname: u.name != null ? u.name : "", }) ); ormPMock.createPerson.mockImplementation((p) => Promise.resolve({ person_id: 1234, - firstname: p.firstname, - lastname: p.lastname, + name: p.name, github: orNull(p.github), github_id: orNull(p.github_id), email: orNull(p.email), @@ -127,12 +126,14 @@ function expectNoCall(func: T) { } test("Can generate and validate states", () => { - expect(github.checkState(github.genState())).toBe(true); + expect( + github.checkState(github.genState(process.env.FRONTEND as string)) + ).toBe(process.env.FRONTEND as string); }); test("A state is valid only once", () => { - const state = github.genState(); - expect(github.checkState(state)).toBe(true); + const state = github.genState(process.env.FRONTEND as string); + expect(github.checkState(state)).toBe(process.env.FRONTEND as string); expect(github.checkState(state)).toBe(false); }); @@ -144,10 +145,10 @@ test("ghIdentity correctly redirects", async () => { "state="; utilMock.redirect.mockReset(); utilMock.redirect.mockImplementation(async (_, url) => { - await expect(url).toBe(exp + github.states[0]); + expect(url).toBe(exp + Object.keys(github.states)[0]); }); - await github.ghIdentity(getMockRes().res); + await github.ghIdentity(getMockReq(), getMockRes().res); }); test("Can parse GH login", async () => { @@ -180,7 +181,7 @@ test("Can detect if name changes are required", () => { const base_person = { github: "", person_id: 78645312, - firstname: "", + name: "", login_user: null, }; @@ -193,33 +194,38 @@ test("Can detect if name changes are required", () => { expect( github.githubNameChange( { ...base_login, name: "abcd" }, - { ...base_person, firstname: "cdef" } + { ...base_person, name: "cdef" } ) ).toBeTruthy(); expect( github.githubNameChange( { ...base_login, login: "abcd", name: "cdef" }, - { ...base_person, github: "cdef", firstname: "cdef" } + { ...base_person, github: "cdef", name: "cdef" } ) ).toBeTruthy(); expect( github.githubNameChange( { ...base_login, login: "cdef", name: "abcd" }, - { ...base_person, github: "cdef", firstname: "cdef" } + { ...base_person, github: "cdef", name: "cdef" } ) ).toBeTruthy(); expect( github.githubNameChange( { ...base_login, login: "abcd", name: "cdef" }, - { ...base_person, github: "abcd", firstname: "cdef" } + { ...base_person, github: "abcd", name: "cdef" } ) ).toBeFalsy(); }); test("Can login if the account exists", async () => { const input = { login: "@my_github", name: "my", id: "69" }; - const output = { sessionkey: "abcd", is_admin: true, is_coach: true }; + const output = { + sessionkey: "abcd", + is_admin: true, + is_coach: true, + is_signup: false, + }; const f = new Date(Date.now()); f.setDate(f.getDate() + session_key.valid_period); @@ -235,7 +241,12 @@ test("Can login if the account exists", async () => { test("Can login if the account exists and update username", async () => { const input = { login: "@my_github", name: "alo", id: "69" }; - const output = { sessionkey: "abcd", is_admin: true, is_coach: true }; + const output = { + sessionkey: "abcd", + is_admin: true, + is_coach: true, + is_signup: false, + }; const f = new Date(Date.now()); f.setDate(f.getDate() + session_key.valid_period); @@ -248,7 +259,7 @@ test("Can login if the account exists and update username", async () => { expect(ormP.updatePerson).toHaveBeenCalledWith({ personId: 69, github: "@my_github", - firstname: "alo", + name: "alo", }); expectNoCall(ormLU.createLoginUser); expectNoCall(ormP.createPerson); @@ -256,7 +267,12 @@ test("Can login if the account exists and update username", async () => { test("Can login if the account exists and update github handle", async () => { const input = { login: "@jefke", name: "my", id: "69" }; - const output = { sessionkey: "abcd", is_admin: true, is_coach: true }; + const output = { + sessionkey: "abcd", + is_admin: true, + is_coach: true, + is_signup: false, + }; const f = new Date(Date.now()); f.setDate(f.getDate() + session_key.valid_period); @@ -269,7 +285,7 @@ test("Can login if the account exists and update github handle", async () => { expect(ormP.updatePerson).toHaveBeenCalledWith({ personId: 69, github: "@jefke", - firstname: "my", + name: "my", }); expectNoCall(ormLU.createLoginUser); expectNoCall(ormP.createPerson); @@ -277,7 +293,12 @@ test("Can login if the account exists and update github handle", async () => { test("Can register if account doesn't exist", async () => { const input = { login: "@jefke", name: "my", id: "-69" }; - const output = { sessionkey: "abcd", is_admin: false, is_coach: true }; + const output = { + sessionkey: "abcd", + is_admin: false, + is_coach: true, + is_signup: true, + }; const f = new Date(Date.now()); f.setDate(f.getDate() + session_key.valid_period); @@ -285,8 +306,7 @@ test("Can register if account doesn't exist", async () => { expectCall(ormPMock.getPasswordPersonByGithub, "-69"); expectCall(ormP.createPerson, { github: "@jefke", - firstname: "my", - lastname: "", + name: "my", github_id: "-69", }); expectCall(ormLU.createLoginUser, { @@ -301,7 +321,7 @@ test("Can register if account doesn't exist", async () => { expectNoCall(ormP.updatePerson); }); -test("Login/Register fails if the request is incorrect", async () => { +test("Login/Register test_fails if the request is incorrect", async () => { const req = getMockReq(); const res = getMockRes().res; @@ -351,13 +371,16 @@ test("Can exchange access token for session key", async () => { }); utilMock.redirect.mockImplementation(async (_, url) => { - expect(url).toBe(process.env.FRONTEND + "/login/abcd"); + expect(url).toBe(process.env.FRONTEND + "/login/abcd?is_signup=false"); return Promise.resolve(); }); const req = getMockReq(); const res = getMockRes().res; - req.query = { code: code, state: github.genState() }; + req.query = { + code: code, + state: github.genState(process.env.FRONTEND as string), + }; return expect( github.ghExchangeAccessToken(req, res) ).resolves.not.toThrow(); @@ -377,8 +400,87 @@ test("Can handle internet issues", async () => { const req = getMockReq(); const res = getMockRes().res; - req.query = { code: "code", state: github.genState() }; + req.query = { + code: "code", + state: github.genState(process.env.FRONTEND as string), + }; return expect( github.ghExchangeAccessToken(req, res) ).resolves.not.toThrow(); }); + +test("Can handle database failures", async () => { + ormPMock.getPasswordPersonByGithub.mockReset(); + ormPMock.getPasswordPersonByGithub.mockRejectedValue({ some: "error" }); + + await expect( + github.ghSignupOrLogin({ login: "", name: "", id: "" }) + ).rejects.toStrictEqual({ some: "error" }); +}); + +test("Can handle different frontend", async () => { + const code = "abcdefghijklmnopqrstuvwxyz"; + const url = "https://other.url"; + const codeIdx = Object.keys(github.states).length; + + axiosMock.post.mockImplementation((url, body, conf) => { + expect(url).toBe("https://github.com/login/oauth/access_token"); + expect(conf).toHaveProperty("headers.Accept", "application/json"); + expect(body).toStrictEqual({ + client_id: process.env.GITHUB_CLIENT_ID, + client_secret: process.env.GITHUB_SECRET, + code: code as string, + redirect_uri: + github.getHome() + config.global.preferred + "/github/login", + }); + return Promise.resolve({ data: { access_token: "some_token" } }); + }); + + axiosMock.get.mockImplementation((url, conf) => { + expect(url).toBe("https://api.github.com/user"); + expect(conf).toHaveProperty( + "headers.Authorization", + "token some_token" + ); + + return Promise.resolve({ + data: { login: "@my_github", name: "my", id: 69 }, + }); + }); + + let expUrl = ""; + + utilMock.redirect.mockImplementation(async (_, url) => { + if (expUrl == "") { + expUrl = + "https://github.com/login/oauth/authorize?client_id=undefined" + + "&allow_signup=true&redirect_uri=undefined%2Fapi-osoc%2Fgithub%2Fchallenge" + + "&state=" + + Object.keys(github.states)[codeIdx]; + } + + expect(url).toBe(expUrl); + // expect(url).toBe(process.env.FRONTEND + "/login/abcd?is_signup=false"); + return Promise.resolve(); + }); + + const req1 = getMockReq(); + const res1 = getMockRes().res; + + req1.body = { callback: url }; + + await github.ghIdentity(req1, res1); + const state = Object.keys(github.states)[codeIdx]; + + expUrl = url + "/login/abcd?is_signup=false"; + + const req2 = getMockReq(); + const res2 = getMockRes().res; + req2.query = { + code: code, + state: state, + }; + return expect( + github.ghExchangeAccessToken(req2, res2) + ).resolves.not.toThrow(); +}); diff --git a/backend/tests/routes_unit/login.test.ts b/backend/tests/routes_unit/login.test.ts new file mode 100644 index 00000000..372eac18 --- /dev/null +++ b/backend/tests/routes_unit/login.test.ts @@ -0,0 +1,300 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { account_status_enum } from "@prisma/client"; + +// setup mock for request +import * as req from "../../request"; +jest.mock("../../request"); +const reqMock = req as jest.Mocked; + +// setup mock for utility +import * as util from "../../utility"; +jest.mock("../../utility", () => { + const og = jest.requireActual("../../utility"); + return { + ...og, + checkSessionKey: jest.fn(), + generateKey: jest.fn(), + }; // we want to only mock checkSessionKey and isAdmin +}); +const utilMock = util as jest.Mocked; + +// setup mocks for orm +import * as session_key from "../../orm_functions/session_key"; +jest.mock("../../orm_functions/session_key"); +const session_keyMock = session_key as jest.Mocked; + +import * as person from "../../orm_functions/person"; +jest.mock("../../orm_functions/person"); +const personMock = person as jest.Mocked; + +// setup mocks for bcrypt +import * as bcrypt from "bcrypt"; +jest.mock("bcrypt"); +const bcryptMock = bcrypt as jest.Mocked; + +import * as login from "../../routes/login"; +import * as skconf from "../../routes/session_key.json"; + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +function expectNoCall(func: T) { + expect(func).toHaveBeenCalledTimes(0); +} + +type Temp = { + email: string; + user: { + password: string; + login_user_id: number; + account_status: account_status_enum; + is_admin: boolean; + is_coach: boolean; + }; +}; + +const users: Temp[] = [ + { + email: "mail1@mail.com", + user: { + password: "pass1", + login_user_id: 0, + account_status: "ACTIVATED", + is_admin: false, + is_coach: false, + }, + }, + { + email: "mail2@mail.com", + user: { + password: "pass2", + login_user_id: 2, + account_status: "DISABLED", + is_admin: false, + is_coach: false, + }, + }, + { + email: "mail3@mail.com", + user: { + password: "pass3", + login_user_id: 4, + account_status: "PENDING", + is_admin: false, + is_coach: false, + }, + }, +]; + +const passErr = { + http: 409, + reason: "Invalid e-mail or password.", +}; + +const disableErr = { + http: 409, + reason: "Account is disabled.", +}; + +const realDateNow = Date.now.bind(global.Date); +const dateNowStub = jest.fn(() => 9846531); + +beforeEach(() => { + reqMock.parseLoginRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseLogoutRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + + bcryptMock.compare.mockImplementation((x, y) => x == y); + + personMock.getPasswordPersonByEmail.mockImplementation((mail) => { + if (mail == users[0].email) + return Promise.resolve({ login_user: users[0].user }); + if (mail == users[1].email) + return Promise.resolve({ login_user: users[1].user }); + if (mail == users[2].email) + return Promise.resolve({ login_user: users[2].user }); + return Promise.resolve(null); + }); + + session_keyMock.addSessionKey.mockImplementation((id, k, d) => + Promise.resolve({ + session_key_id: 0, + session_key: k, + login_user_id: id, + valid_until: d, + }) + ); + session_keyMock.removeAllKeysForUser.mockImplementation(() => + Promise.resolve({ count: 5 }) + ); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }) + ); + utilMock.generateKey.mockReturnValue("abcd"); + global.Date.now = dateNowStub; +}); + +afterEach(() => { + reqMock.parseLoginRequest.mockReset(); + reqMock.parseLogoutRequest.mockReset(); + + bcryptMock.compare.mockReset(); + + personMock.getPasswordPersonByEmail.mockReset(); + + session_keyMock.addSessionKey.mockReset(); + session_keyMock.removeAllKeysForUser.mockReset(); + + utilMock.checkSessionKey.mockReset(); + utilMock.generateKey.mockReset(); + global.Date.now = realDateNow; +}); + +test("Can login with valid credentials", async () => { + const rq = getMockReq(); + rq.body = { name: users[0].email, pass: users[0].user.password }; + const fdate = new Date(Date.now()); + fdate.setDate(fdate.getDate() + skconf.valid_period); + + await expect(login.login(rq)).resolves.toStrictEqual({ + sessionkey: "abcd", + is_admin: false, + is_coach: false, + account_status: "ACTIVATED", + }); + expectCall(reqMock.parseLoginRequest, rq); + expectCall(personMock.getPasswordPersonByEmail, users[0].email); + expect(utilMock.generateKey).toHaveBeenCalledTimes(1); + expect(session_keyMock.addSessionKey).toHaveBeenCalledTimes(1); + expect(session_keyMock.addSessionKey).toHaveBeenCalledWith( + users[0].user.login_user_id, + "abcd", + fdate + ); +}); + +test("Can login with valid credentials (PENDING)", async () => { + const rq = getMockReq(); + rq.body = { name: users[2].email, pass: users[2].user.password }; + const fdate = new Date(Date.now()); + fdate.setDate(fdate.getDate() + skconf.valid_period); + + await expect(login.login(rq)).resolves.toStrictEqual({ + sessionkey: "abcd", + is_admin: false, + is_coach: false, + account_status: "PENDING", + }); + expectCall(reqMock.parseLoginRequest, rq); + expectCall(personMock.getPasswordPersonByEmail, users[2].email); + expect(utilMock.generateKey).toHaveBeenCalledTimes(1); + expect(session_keyMock.addSessionKey).toHaveBeenCalledTimes(1); + expect(session_keyMock.addSessionKey).toHaveBeenCalledWith( + users[2].user.login_user_id, + "abcd", + fdate + ); +}); + +test("Can handle invalid password", async () => { + const rq = getMockReq(); + rq.body = { name: users[2].email, pass: users[1].user.password }; + + await expect(login.login(rq)).rejects.toStrictEqual(passErr); + expectCall(reqMock.parseLoginRequest, rq); + expectCall(personMock.getPasswordPersonByEmail, users[2].email); + expectNoCall(utilMock.generateKey); + expectNoCall(session_keyMock.addSessionKey); +}); + +test("Can handle invalid email", async () => { + const rq = getMockReq(); + rq.body = { name: "mail000@mail.com", pass: users[2].user.password }; + + await expect(login.login(rq)).rejects.toStrictEqual(passErr); + expectCall(reqMock.parseLoginRequest, rq); + expectCall(personMock.getPasswordPersonByEmail, "mail000@mail.com"); + expectNoCall(utilMock.generateKey); + expectNoCall(session_keyMock.addSessionKey); +}); + +test("Can handle disabled accounts", async () => { + const rq = getMockReq(); + rq.body = { name: users[1].email, pass: users[1].user.password }; + + await expect(login.login(rq)).rejects.toStrictEqual(disableErr); + expectCall(reqMock.parseLoginRequest, rq); + expectCall(personMock.getPasswordPersonByEmail, users[1].email); + expectNoCall(utilMock.generateKey); + expectNoCall(session_keyMock.addSessionKey); +}); + +test("Can logout", async () => { + const rq = getMockReq(); + rq.body = { sessionkey: "abcd" }; + await expect(login.logout(rq)).resolves.toStrictEqual({}); + expectCall(reqMock.parseLogoutRequest, rq); + expect(util.checkSessionKey).toHaveBeenCalledTimes(1); + expect(util.checkSessionKey).toHaveBeenCalledWith( + { sessionkey: "abcd" }, + false + ); + expectCall(session_keyMock.removeAllKeysForUser, "abcd"); +}); + +test("Edge case", async () => { + personMock.getPasswordPersonByEmail.mockImplementation((name) => { + if (name == "mail_00@00.com") { + return Promise.resolve({ login_user: null }); + } + return Promise.resolve({ + login_user: { + login_user_id: 0, + password: null, + account_status: "ENABLED" as account_status_enum, + is_admin: false, + is_coach: false, + }, + }); + }); + + // edge case 1 + { + const req = getMockReq(); + req.body = { name: "mail_00@00.com", pass: "" }; + await expect(login.login(req)).rejects.toStrictEqual({ + http: 409, + reason: "Invalid e-mail or password.", + }); + } + + // edge case 2 + { + const req = getMockReq(); + req.body = { name: "mail_01@00.com", pass: "" }; + await expect(login.login(req)).rejects.toStrictEqual({ + http: 409, + reason: "Invalid e-mail or password.", + }); + } +}); diff --git a/backend/tests/routes_unit/osoc.test.ts b/backend/tests/routes_unit/osoc.test.ts new file mode 100644 index 00000000..364f3b05 --- /dev/null +++ b/backend/tests/routes_unit/osoc.test.ts @@ -0,0 +1,236 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { WithUserID } from "../../types"; + +// setup mock for request +import * as req from "../../request"; +jest.mock("../../request"); +const reqMock = req as jest.Mocked; + +// setup mock for utility +import * as util from "../../utility"; +jest.mock("../../utility", () => { + const og = jest.requireActual("../../utility"); + return { + ...og, + checkSessionKey: jest.fn(), + isAdmin: jest.fn(), + checkYearPermissionOsoc: jest.fn(), + }; // we want to only mock checkSessionKey, isAdmin and checkYearPermissionOsoc +}); +const utilMock = util as jest.Mocked; + +// setup mocks for orm +import * as ormo from "../../orm_functions/osoc"; +jest.mock("../../orm_functions/osoc"); +const ormoMock = ormo as jest.Mocked; + +import * as osoc from "../../routes/osoc"; + +import * as ormlo from "../../orm_functions/login_user_osoc"; +import { errors } from "../../utility"; +jest.mock("../../orm_functions/login_user_osoc"); +const ormloMock = ormlo as jest.Mocked; + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +function expectNoCall(func: T) { + expect(func).toHaveBeenCalledTimes(0); +} + +type KD = { abcd: WithUserID; defg: WithUserID }; +function keyData(v: T): KD { + return { + abcd: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }, + defg: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }, + }; +} + +const osocs = [ + { osoc_id: 1, year: 2022, _count: { project: 5 } }, + { osoc_id: 49, year: 2054, _count: { project: 895 } }, + { osoc_id: 4, year: 2024, _count: { project: 7894512 } }, +]; + +beforeEach(() => { + reqMock.parseNewOsocEditionRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseOsocAllRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseFilterOsocsRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseDeleteOsocEditionRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }) + ); + utilMock.isAdmin.mockImplementation((v) => + v.sessionkey == "abcd" + ? Promise.resolve(keyData(v).abcd) + : Promise.reject(util.errors.cookInsufficientRights()) + ); + utilMock.checkYearPermissionOsoc.mockImplementation((v) => + Promise.resolve(v) + ); + + ormoMock.createOsoc.mockImplementation((y) => + Promise.resolve({ osoc_id: 0, year: y }) + ); + ormoMock.getAllOsoc.mockResolvedValue(osocs); + ormoMock.filterOsocs.mockImplementation( + (_, f: number | undefined, s: string | undefined) => { + let data = osocs; + if (f != undefined) data = data.filter((v) => v.year == f); + if (s != undefined) + data = data.sort( + (a, b) => (s == "desc" ? -1 : 1) * (a.year - b.year) + ); + return Promise.resolve({ + pagination: { page: 0, count: 7 }, + data: data, + }); + } + ); + ormoMock.deleteOsocFromDB.mockImplementation(() => Promise.resolve()); + + ormloMock.addOsocToUser.mockResolvedValue({ + login_user_osoc_id: 0, + login_user_id: 0, + osoc_id: 0, + }); +}); + +afterEach(() => { + reqMock.parseNewOsocEditionRequest.mockReset(); + reqMock.parseOsocAllRequest.mockReset(); + reqMock.parseFilterOsocsRequest.mockReset(); + reqMock.parseDeleteOsocEditionRequest.mockReset(); + + utilMock.checkSessionKey.mockReset(); + utilMock.isAdmin.mockReset(); + utilMock.checkYearPermissionOsoc.mockReset(); + + ormoMock.createOsoc.mockReset(); + ormoMock.getAllOsoc.mockReset(); + ormoMock.filterOsocs.mockReset(); + ormoMock.deleteOsocFromDB.mockReset(); + + ormloMock.addOsocToUser.mockReset(); +}); + +test("Can create osoc edition", async () => { + const r = getMockReq(); + r.body = { sessionkey: "abcd", year: 2059 }; + await expect(osoc.createOsocEdition(r)).resolves.toStrictEqual({ + data: { id: 0, year: 2059 }, + }); + expectCall(reqMock.parseNewOsocEditionRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.createOsoc, 2059); + expectNoCall(utilMock.checkSessionKey); +}); + +test("osoc create fails because of database error when connecting loginUser to osoc", async () => { + const r = getMockReq(); + ormloMock.addOsocToUser.mockReset(); // resetting this mock will trigger the fail + r.body = { sessionkey: "abcd", year: 2059 }; + + await expect(osoc.createOsocEdition(r)).rejects.toBe( + errors.cookServerError() + ); + + expectCall(reqMock.parseNewOsocEditionRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.createOsoc, 2059); + expectNoCall(utilMock.checkSessionKey); +}); + +test("Can get all the osoc editions", async () => { + const r = getMockReq(); + r.body = { sessionkey: "abcd" }; + await expect(osoc.listOsocEditions(r)).resolves.toStrictEqual({ + data: osocs, + }); + expectCall(reqMock.parseOsocAllRequest, r); + expect(ormoMock.getAllOsoc).toHaveBeenCalledTimes(1); + expectCall(utilMock.isAdmin, r.body); +}); + +test("Can't get all the osoc editions if you're a coach", async () => { + const r = getMockReq(); + r.body = { sessionkey: "abcd" }; + + utilMock.isAdmin.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }) + ); + + await expect(osoc.listOsocEditions(r)).rejects.toBe(errors.cookInvalidID()); + + utilMock.isAdmin.mockReset(); +}); + +test("Can filter the osoc editions", async () => { + const r = getMockReq(); + r.body = { sessionkey: "abcd", yearFilter: 2022 }; + await expect(osoc.filterYear(r)).resolves.toStrictEqual({ + data: [{ osoc_id: 1, year: 2022, _count: { project: 5 } }], + pagination: { page: 0, count: 7 }, + }); + expectCall(reqMock.parseFilterOsocsRequest, r); + expect(ormoMock.filterOsocs).toHaveBeenCalledTimes(1); + expect(ormoMock.filterOsocs).toHaveBeenCalledWith( + { currentPage: undefined, pageSize: undefined }, + 2022, + undefined, + 0 + ); + expectCall(utilMock.checkSessionKey, r.body); +}); + +test("Can delete an osoc edition by id", async () => { + const r = getMockReq(); + r.body = { sessionkey: "abcd", id: 4 }; + await expect(osoc.deleteOsocEditionRequest(r)).resolves.toStrictEqual({}); + expectCall(reqMock.parseDeleteOsocEditionRequest, r); + expectCall(ormoMock.deleteOsocFromDB, 4); + expectCall(utilMock.isAdmin, r.body); +}); diff --git a/backend/tests/routes_unit/project.test.ts b/backend/tests/routes_unit/project.test.ts new file mode 100644 index 00000000..7317500e --- /dev/null +++ b/backend/tests/routes_unit/project.test.ts @@ -0,0 +1,3003 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import * as prisma from "@prisma/client"; + +import { errors } from "../../utility"; + +// import & mock +import * as rq from "../../request"; +jest.mock("../../request"); +const reqMock = rq as jest.Mocked; + +import * as util from "../../utility"; +jest.mock("../../utility"); +const utilMock = util as jest.Mocked; + +import * as ormPr from "../../orm_functions/project"; +jest.mock("../../orm_functions/project"); +const ormPrMock = ormPr as jest.Mocked; + +import * as ormJ from "../../orm_functions/job_application"; +jest.mock("../../orm_functions/job_application"); +const ormJMock = ormJ as jest.Mocked; + +import * as ormRole from "../../orm_functions/role"; +jest.mock("../../orm_functions/role"); +const ormRMock = ormRole as jest.Mocked; + +import * as ormPrRole from "../../orm_functions/project_role"; +jest.mock("../../orm_functions/project_role"); +const ormPrRMock = ormPrRole as jest.Mocked; + +import * as ormCtr from "../../orm_functions/contract"; +jest.mock("../../orm_functions/contract"); +const ormCMock = ormCtr as jest.Mocked; + +import * as ormPU from "../../orm_functions/project_user"; +jest.mock("../../orm_functions/project_user"); +const ormPUMock = ormPU as jest.Mocked; + +import * as ormLU from "../../orm_functions/login_user"; +jest.mock("../../orm_functions/login_user"); +const ormLUMock = ormLU as jest.Mocked; + +import * as ormEv from "../../orm_functions/evaluation"; +jest.mock("../../orm_functions/evaluation"); +const ormEvMock = ormEv as jest.Mocked; + +import * as ormO from "../../orm_functions/osoc"; +jest.mock("../../orm_functions/osoc"); +const ormOMock = ormO as jest.Mocked; + +import * as project from "../../routes/project"; +import { CreateProject } from "../../orm_functions/orm_types"; +import { contract_status_enum } from "@prisma/client"; + +const realDateNow = Date.now.bind(global.Date); +const dateNowStub = jest.fn(() => 123456789); + +function newProject(v: CreateProject): prisma.project { + return { + project_id: 0, + name: v.name, + osoc_id: 0, + partner: v.partner, + description: v.description, + start_date: v.startDate, + end_date: v.endDate, + }; +} + +type studenttype = { + student_id: number; + gender: string; + pronouns: string | null; + phone_number: string; + nickname: string | null; + alumni: boolean; + person: prisma.person; +} | null; + +type rolestype = { + positions: number; + project_id: number; + project_role_id: number; + role_id: number; + role: { + name: string; + }; +}; + +type contrtype = { + contract_status: prisma.contract_status_enum; + contract_id: number; + student: studenttype; + project_role: rolestype; + login_user: { + login_user_id: number; + is_admin: boolean; + is_coach: boolean; + person: prisma.person; + }; +}; + +const roles: prisma.role[] = [ + { role_id: 0, name: "dev" }, + { role_id: 1, name: "backend" }, + { role_id: 2, name: "frontend" }, + { role_id: 3, name: "full-stack" }, + { role_id: 4, name: "procrastinator" }, +]; + +const projects: prisma.project[] = [ + { + project_id: 0, + name: "sample project", + osoc_id: 0, + partner: "jefke", + description: null, + start_date: new Date(Date.now()), + end_date: new Date(Date.now()), + }, + { + project_id: 1, + name: "other project", + osoc_id: 0, + partner: "not jefke", + description: "def not a project for jefke", + start_date: new Date(Date.now()), + end_date: new Date(Date.now()), + }, +]; + +const projects2: (prisma.project & { osoc: prisma.osoc })[] = [ + { + project_id: 0, + name: "sample project", + osoc_id: 0, + partner: "jefke", + description: null, + start_date: new Date(Date.now()), + end_date: new Date(Date.now()), + osoc: { + osoc_id: 0, + year: 2022, + }, + }, + { + project_id: 1, + name: "other project", + osoc_id: 0, + partner: "not jefke", + description: "def not a project for jefke", + start_date: new Date(Date.now()), + end_date: new Date(Date.now()), + osoc: { + osoc_id: 0, + year: 2022, + }, + }, +]; + +const projectroles: prisma.project_role[] = [ + { project_role_id: 0, project_id: 0, role_id: 0, positions: 3 }, + { project_role_id: 1, project_id: 1, role_id: 1, positions: 4 }, + { project_role_id: 2, project_id: 0, role_id: 2, positions: 7 }, + { project_role_id: 3, project_id: 1, role_id: 3, positions: 2 }, + { project_role_id: 4, project_id: 0, role_id: 4, positions: 7 }, +]; + +const people: prisma.person[] = [ + { + person_id: 0, + email: "jeff@gmail.com", + github: null, + github_id: null, + name: "jeff", + }, + { + person_id: 1, + email: "marie@gmail.com", + github: null, + github_id: null, + name: "marie", + }, + { + person_id: 2, + email: "gget@gmail.com", + github: null, + github_id: null, + name: "georgette", + }, + { + person_id: 3, + email: "stef@gmail.com", + github: null, + github_id: null, + name: "stef", + }, + { + person_id: 4, + email: "jean@gmail.com", + github: null, + github_id: null, + name: "jean", + }, + { + person_id: 5, + email: "karen@manager.com", + github: null, + github_id: null, + name: "karen", + }, + + { + person_id: 6, + email: null, + github: "@admin", + github_id: "null", + name: "adminboi", + }, +]; + +const students: studenttype[] = [ + { + student_id: 0, + gender: "one", + pronouns: null, + phone_number: "04", + nickname: null, + alumni: false, + person: people[0], + }, + { + student_id: 1, + gender: "two", + pronouns: null, + phone_number: "04", + nickname: null, + alumni: false, + person: people[1], + }, + { + student_id: 2, + gender: "three", + pronouns: null, + phone_number: "04", + nickname: null, + alumni: false, + person: people[2], + }, + { + student_id: 3, + gender: "four", + pronouns: null, + phone_number: "04", + nickname: null, + alumni: false, + person: people[3], + }, + { + student_id: 4, + gender: "five", + pronouns: null, + phone_number: "04", + nickname: null, + alumni: false, + person: people[4], + }, + { + student_id: 5, + gender: "six", + pronouns: null, + phone_number: "04", + nickname: null, + alumni: false, + person: people[5], + }, +]; + +const deltaroles: rolestype[] = [ + { ...projectroles[0], role: { ...roles[0] } }, + { ...projectroles[1], role: { ...roles[1] } }, + { ...projectroles[2], role: { ...roles[2] } }, + { ...projectroles[3], role: { ...roles[3] } }, + { ...projectroles[4], role: { ...roles[4] } }, +]; + +const loginuser: contrtype["login_user"] = { + is_admin: true, + is_coach: false, + login_user_id: 0, + person: people[5], +}; + +const contracts: contrtype[] = [ + { + contract_status: "DRAFT", + contract_id: 0, + student: students[0], + project_role: deltaroles[0], + login_user: loginuser, + }, + { + contract_status: "DRAFT", + contract_id: 1, + student: students[1], + project_role: deltaroles[1], + login_user: loginuser, + }, + { + contract_status: "DRAFT", + contract_id: 2, + student: students[2], + project_role: deltaroles[2], + login_user: loginuser, + }, + { + contract_status: "DRAFT", + contract_id: 3, + student: students[3], + project_role: deltaroles[3], + login_user: loginuser, + }, + { + contract_status: "DRAFT", + contract_id: 4, + student: students[4], + project_role: deltaroles[4], + login_user: loginuser, + }, +]; + +const studcontr = [ + { + student: { + student_id: 0, + person_id: 0, + gender: "apache attack heli", + pronouns: null, + phone_number: "+32", + nickname: null, + alumni: false, + }, + project_role: { + project_id: 0, + project: { osoc_id: 2022 }, + }, + contract_id: 0, + }, + { + student: { + student_id: 1, + person_id: 1, + gender: "apache attack heli", + pronouns: null, + phone_number: "+32", + nickname: null, + alumni: false, + }, + project_role: { + project_id: 0, + project: { osoc_id: 2022 }, + }, + contract_id: 1, + }, +]; + +const evals = [ + { + evaluation_id: 0, + login_user_id: 0, + job_application_id: 0, + decision: "YES" as prisma.decision_enum, + is_final: true, + motivation: null, + }, + { + evaluation_id: 1, + login_user_id: 0, + job_application_id: 1, + decision: "MAYBE" as prisma.decision_enum, + is_final: true, + motivation: null, + }, + { + evaluation_id: 2, + login_user_id: 0, + job_application_id: 2, + decision: "NO" as prisma.decision_enum, + is_final: true, + motivation: null, + }, +]; + +const osocCtr = [ + { project_role: { project: projects[0] }, student_id: 0 }, + { project_role: { project: projects[1] }, student_id: 0 }, + { project_role: { project: projects[1] }, student_id: 1 }, + { project_role: { project: projects[0] }, student_id: 2 }, + { project_role: { project: projects[1] }, student_id: 2 }, + { project_role: { project: projects[1] }, student_id: 3 }, +]; + +function orDefault(v: T | undefined, d: T): T { + return v == undefined ? d : v; +} + +beforeEach(() => { + // date + dateNowStub.mockImplementation(() => 123456789); + global.Date.now = dateNowStub; + + // request + reqMock.parseNewProjectRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseProjectAllRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseUpdateProjectRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseDeleteProjectRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseGetDraftedStudentsRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseDraftStudentRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseRemoveCoachRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseAssignCoachRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseRemoveAssigneeRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseProjectConflictsRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseDraftStudentRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseFilterProjectsRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseSingleProjectRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + + // util + utilMock.isAdmin.mockImplementation((v) => + Promise.resolve({ + data: v, + userId: 0, + is_admin: true, + is_coach: false, + accountStatus: "ACTIVATED", + }) + ); + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + data: v, + userId: 0, + is_admin: true, + is_coach: false, + accountStatus: "ACTIVATED", + }) + ); + utilMock.isValidID.mockImplementation((v) => Promise.resolve(v)); + utilMock.getOrDefault.mockImplementation((v, x) => + v == undefined || v == null ? x : v + ); + utilMock.getOrReject.mockImplementation((v) => + v == undefined || v == null ? Promise.reject({}) : Promise.resolve(v) + ); + + // project orm + ormPrMock.createProject.mockImplementation((v) => + Promise.resolve(newProject(v)) + ); + ormPrMock.getAllProjects.mockResolvedValue(projects); + ormPrMock.updateProject.mockImplementation((v) => + Promise.resolve({ + project_id: v.projectId, + name: orDefault(v.name, "name"), + osoc_id: orDefault(v.osocId, 0), + partner: orDefault(v.partner, "partner"), + description: orDefault(v.description, null), + start_date: orDefault(v.startDate, new Date(1000000)), + end_date: orDefault(v.endDate, new Date(10000000)), + }) + ); + ormPrMock.deleteProject.mockImplementation(() => + Promise.resolve(projects[0]) + ); + ormPrMock.deleteProjectFromDB.mockImplementation(() => Promise.resolve()); + ormPrMock.getProjectById.mockImplementation((id) => + Promise.resolve(projects2[id]) + ); + ormPrMock.filterProjects.mockResolvedValue({ + data: projects.map((x) => ({ + ...x, + project_role: [{ role: { name: "role_1" }, positions: 15 }], + project_user: [ + { login_user: { login_user_id: 1, is_coach: true } }, + ], + })), + pagination: { page: 0, count: projects.length }, + }); + ormPrMock.getProjectById.mockImplementation((id) => + Promise.resolve(id < projects2.length ? projects2[id] : null) + ); + + // role orm + ormRMock.getRolesByName.mockImplementation((rln) => { + const tmp = roles.filter((v) => v.name == rln); + if (tmp.length > 0) return Promise.resolve(tmp[0]); + return Promise.resolve(null); + }); + ormRMock.createRole.mockImplementation((v) => + Promise.resolve({ role_id: 4, name: v }) + ); + ormRMock.getRole.mockImplementation((v) => Promise.resolve(roles[v])); + + // project-role orm + ormPrRMock.createProjectRole.mockImplementation((v) => + Promise.resolve({ + project_role_id: 0, + project_id: v.projectId, + role_id: v.roleId, + positions: v.positions, + }) + ); + ormOMock.getOsocById.mockResolvedValue({ + osoc_id: 0, + year: 2022, + }); + ormPrRMock.getProjectRolesByProject.mockImplementation((id) => + Promise.resolve(projectroles.filter((x) => x.project_id === id)) + ); + ormPrRMock.updateProjectRole.mockImplementation((v) => + Promise.resolve({ + project_role_id: v.projectRoleId, + project_id: v.projectId, + role_id: v.roleId, + positions: v.positions, + }) + ); + ormPrRMock.deleteProjectRole.mockResolvedValue(projectroles[0]); + ormPrRMock.getNumberOfFreePositions.mockImplementation((v) => + Promise.resolve((v + 1) * (v + 2)) + ); + ormPrRMock.getProjectRoleById.mockImplementation((v) => + Promise.resolve({ + ...projectroles[v], + role: { ...roles[v] }, + }) + ); + ormPrRMock.getProjectRoleNamesByProject.mockImplementation((v) => + Promise.resolve( + projectroles + .filter((x) => x.project_id == v) + .map((x) => ({ + ...x, + role: roles[x.role_id], + })) + ) + ); + + // contract orm + ormCMock.contractsByProject.mockImplementation((id) => + Promise.resolve( + contracts.filter((x) => x.project_role.project_id == id) + ) + ); + ormCMock.updateContract.mockImplementation((upd) => + Promise.resolve({ + contract_id: upd.contractId, + loginUserId: upd.loginUserId, + project_role_id: upd.projectRoleId || 0, + student_id: 0, + information: "", + created_by_login_user_id: 0, + contract_status: upd.contractStatus || "DRAFT", + }) + ); + ormCMock.contractsForStudent.mockResolvedValue(studcontr); + ormCMock.removeContract.mockImplementation((v) => + Promise.resolve({ + contract_id: v, + student_id: 0, + created_by_login_user_id: 0, + project_role_id: 0, + information: null, + contract_status: "DRAFT", + }) + ); + ormCMock.sortedContractsByOsocEdition.mockResolvedValue(osocCtr); + ormCMock.createContract.mockImplementation((v) => + Promise.resolve({ + contract_id: 5, + loginUserId: v.loginUserId, + project_role_id: v.projectRoleId || 0, + student_id: v.studentId, + information: v.information || null, + created_by_login_user_id: v.loginUserId, + contract_status: v.contractStatus || "DRAFT", + }) + ); + + // project user orm + ormPUMock.getUsersFor.mockResolvedValue([ + { login_user: loginuser, project_user_id: 0 }, + ]); + ormPUMock.deleteProjectUser.mockImplementation(() => + Promise.resolve({ count: 0 }) + ); + ormPUMock.createProjectUser.mockImplementation((v) => + Promise.resolve({ + login_user_id: v.loginUserId, + project_id: v.projectId, + project_user_id: 0, + }) + ); + + // evaluation orm + ormEvMock.getEvaluationByPartiesFor.mockResolvedValue(evals); + ormEvMock.updateEvaluationForStudent.mockImplementation((v) => + Promise.resolve({ + evaluation_id: v.evaluation_id, + decision: "MAYBE", + login_user_id: v.loginUserId, + motivation: v.motivation || null, + job_application_id: 0, + is_final: true, + }) + ); + + // osoc orm + ormOMock.getNewestOsoc.mockResolvedValue({ osoc_id: 1, year: 2022 }); + ormOMock.getLatestOsoc.mockResolvedValue({ osoc_id: 1, year: 2022 }); +}); + +afterEach(() => { + // date + dateNowStub.mockReset(); + global.Date.now = realDateNow; + + // request + reqMock.parseNewProjectRequest.mockReset(); + reqMock.parseProjectAllRequest.mockReset(); + reqMock.parseUpdateProjectRequest.mockReset(); + reqMock.parseDeleteProjectRequest.mockReset(); + reqMock.parseGetDraftedStudentsRequest.mockReset(); + reqMock.parseDraftStudentRequest.mockReset(); + reqMock.parseRemoveCoachRequest.mockReset(); + reqMock.parseAssignCoachRequest.mockReset(); + reqMock.parseRemoveAssigneeRequest.mockReset(); + reqMock.parseProjectConflictsRequest.mockReset(); + reqMock.parseDraftStudentRequest.mockReset(); + reqMock.parseFilterProjectsRequest.mockReset(); + reqMock.parseSingleProjectRequest.mockReset(); + + // util + utilMock.isAdmin.mockReset(); + utilMock.checkSessionKey.mockReset(); + utilMock.isValidID.mockReset(); + utilMock.getOrDefault.mockReset(); + utilMock.getOrReject.mockReset(); + + // project orm + ormPrMock.createProject.mockReset(); + ormPrMock.getAllProjects.mockReset(); + ormPrMock.updateProject.mockReset(); + ormPrMock.deleteProject.mockReset(); + ormPrMock.deleteProjectFromDB.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormPrMock.filterProjects.mockReset(); + ormPrMock.getProjectById.mockReset(); + + // role orm + ormRMock.getRolesByName.mockReset(); + ormRMock.createRole.mockReset(); + ormRMock.getRole.mockReset(); + + // project-role orm + ormPrRMock.createProjectRole.mockReset(); + ormPrRMock.getProjectRolesByProject.mockReset(); + ormPrRMock.updateProjectRole.mockReset(); + ormPrRMock.deleteProjectRole.mockReset(); + ormPrRMock.getNumberOfFreePositions.mockReset(); + ormPrRMock.getProjectRoleById.mockReset(); + ormPrRMock.getProjectRoleNamesByProject.mockReset(); + + // contract orm + ormCMock.contractsByProject.mockReset(); + ormCMock.updateContract.mockReset(); + ormCMock.removeContract.mockReset(); + ormCMock.contractsForStudent.mockReset(); + ormCMock.removeContract.mockReset(); + ormCMock.sortedContractsByOsocEdition.mockReset(); + ormCMock.createContract.mockReset(); + + // project user orm + ormPUMock.getUsersFor.mockReset(); + ormPUMock.deleteProjectUser.mockReset(); + ormPUMock.createProjectUser.mockReset(); + + // evaluation orm + ormEvMock.getEvaluationByPartiesFor.mockReset(); + ormEvMock.updateEvaluationForStudent.mockReset(); + + // osoc orm + ormOMock.getNewestOsoc.mockReset(); + ormOMock.getLatestOsoc.mockReset(); + ormOMock.getOsocById.mockReset(); +}); + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +test("Can create new projects", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "some-key", + osocId: 0, + name: "Operation Ivy", + partner: "US Goverment", + description: + "Let's build a thermonuclear warhead! What could go wrong?", + start: new Date("January 31, 1950"), + end: new Date("November 15, 1952 23:30:00.0"), + roles: { + roles: [ + { name: "dev", positions: 8 }, + { name: "nuclear bomb engineer", positions: 2 }, + ], + }, + coaches: { + coaches: [0], + }, + }; + + ormLUMock.getOsocYearsForLoginUser.mockResolvedValue([2022]); + + await expect(project.createProject(req)).resolves.toStrictEqual({ + id: 0, + name: req.body.name, + partner: req.body.partner, + start_date: req.body.start.toString(), + end_date: req.body.end.toString(), + osoc_id: 0, + roles: req.body.roles.roles, + description: req.body.description, + coaches: [{ login_user: loginuser, project_user_id: 0 }], + }); + expectCall(reqMock.parseNewProjectRequest, req); + expectCall(utilMock.isAdmin, req.body); + expectCall(ormPrMock.createProject, { + name: req.body.name, + partner: req.body.partner, + startDate: req.body.start, + endDate: req.body.end, + osocId: req.body.osocId, + description: req.body.description, + }); + expect(ormRMock.getRolesByName).toHaveBeenCalledTimes(2); + expectCall(ormRMock.createRole, req.body.roles.roles[1].name); + expect(ormPrRMock.createProjectRole).toHaveBeenCalledTimes(2); + + ormLUMock.getOsocYearsForLoginUser.mockReset(); +}); + +test("Can create new projects (insufficient rights)", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "some-key", + osocId: 0, + name: "Operation Ivy", + partner: "US Goverment", + description: + "Let's build a thermonuclear warhead! What could go wrong?", + start: new Date("January 31, 1950"), + end: new Date("November 15, 1952 23:30:00.0"), + roles: { + roles: [ + { name: "dev", positions: 8 }, + { name: "nuclear bomb engineer", positions: 2 }, + ], + }, + coaches: { + coaches: [0], + }, + }; + + ormLUMock.getOsocYearsForLoginUser.mockResolvedValue([2023]); + + ormOMock.getOsocById.mockResolvedValue({ + osoc_id: 0, + year: 2022, + }); + + await expect(project.createProject(req)).rejects.toBe( + errors.cookInsufficientRights() + ); + + ormLUMock.getOsocYearsForLoginUser.mockReset(); + ormOMock.getOsocById.mockReset(); +}); + +test("Can list all projects", async () => { + const req = getMockReq(); + req.body = { sessionkey: "key" }; + + // I'm too exhausted to even try to reconstruct this... + // I mean... there's no use in reimplementing the function here, right? + await expect(project.listProjects(req)).resolves.not.toThrow(); + expectCall(reqMock.parseProjectAllRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + + expect(ormPrMock.getAllProjects).toHaveBeenCalledTimes(0); + expect(ormPrRMock.getProjectRolesByProject).toHaveBeenCalledTimes( + projects.length + ); + expect(ormRMock.getRole).toHaveBeenCalledTimes(roles.length); + expect(ormCMock.contractsByProject).toHaveBeenCalledTimes(projects.length); + expect(ormPUMock.getUsersFor).toHaveBeenCalledTimes(projects.length); +}); + +test("Can't list all projects (role failure)", async () => { + ormRMock.getRole.mockResolvedValue(null); + const req = getMockReq(); + req.body = { sessionkey: "key" }; + + await expect(project.listProjects(req)).rejects.toStrictEqual(undefined); + expectCall(reqMock.parseProjectAllRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + + expect(ormPrMock.getAllProjects).toHaveBeenCalledTimes(0); + expect(ormPrRMock.getProjectRolesByProject).toHaveBeenCalledTimes(1); + expect(ormRMock.getRole).toHaveBeenCalledTimes(1); + expect(ormCMock.contractsByProject).not.toHaveBeenCalled(); + expect(ormPUMock.getUsersFor).not.toHaveBeenCalled(); +}); + +test("Can get single project", async () => { + ormCMock.contractsByProject.mockResolvedValue([contracts[0]]); + const req = getMockReq(); + req.body = { sessionkey: "key", id: 0 }; + + const res = { + id: projects[0].project_id, + description: null, + name: projects[0].name, + partner: projects[0].partner, + start_date: projects[0].start_date.toString(), + end_date: projects[0].end_date.toString(), + osoc_id: projects[0].osoc_id, + roles: [ + { name: roles[0].name, positions: projectroles[0].positions }, + { name: roles[2].name, positions: projectroles[2].positions }, + { name: roles[4].name, positions: projectroles[4].positions }, + ], + coaches: [{ login_user: loginuser, project_user_id: 0 }], + contracts: [ + { + contract_id: 0, + contract_status: "DRAFT", + login_user: { + is_admin: true, + is_coach: false, + login_user_id: 0, + person: { + email: "karen@manager.com", + github: null, + github_id: null, + name: "karen", + person_id: 5, + }, + }, + project_role: { + positions: 3, + project_id: 0, + project_role_id: 0, + role: { + name: "dev", + role_id: 0, + }, + role_id: 0, + }, + student: { + evaluation: undefined, + evaluations: undefined, + jobApplication: undefined, + roles: undefined, + student: { + alumni: false, + gender: "one", + nickname: null, + person: { + email: "jeff@gmail.com", + github: null, + github_id: null, + name: "jeff", + person_id: 0, + }, + person_id: undefined, + phone_number: "04", + pronouns: null, + student_id: 0, + }, + }, + }, + ], + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + await expect(project.getProject(req)).resolves.toStrictEqual(res); + expectCall(reqMock.parseSingleProjectRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.isValidID).toHaveBeenCalledTimes(1); + expectCall(ormPrMock.getProjectById, 0); + expectCall(ormCMock.contractsByProject, 0); + expectCall(ormPrRMock.getProjectRolesByProject, 0); + expect(ormRMock.getRole).toHaveBeenCalledTimes(3); + expectCall(ormPU.getUsersFor, 0); + + utilMock.checkYearPermissionProject.mockReset(); +}); + +test("Can't get single project (role error)", async () => { + ormCMock.contractsByProject.mockResolvedValue([contracts[0]]); + ormRMock.getRole.mockResolvedValue(null); + const req = getMockReq(); + req.body = { sessionkey: "key", id: 0 }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + await expect(project.getProject(req)).rejects.toStrictEqual(undefined); + expectCall(reqMock.parseSingleProjectRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.isValidID).toHaveBeenCalledTimes(1); + expectCall(ormPrMock.getProjectById, 0); + expectCall(ormCMock.contractsByProject, 0); + expectCall(ormPrRMock.getProjectRolesByProject, 0); + expect(ormRMock.getRole).toHaveBeenCalledTimes(1); + expect(ormPU.getUsersFor).not.toHaveBeenCalled(); + + utilMock.checkYearPermissionProject.mockReset(); +}); + +test("Can't get single project (ID error)", async () => { + ormPrMock.getProjectById.mockResolvedValue(null); + const req = getMockReq(); + req.body = { sessionkey: "key", id: 0 }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + await expect(project.getProject(req)).rejects.toStrictEqual(undefined); + expectCall(reqMock.parseSingleProjectRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.isValidID).toHaveBeenCalledTimes(1); + expectCall(ormPrMock.getProjectById, 0); + expect(ormCMock.contractsByProject).not.toHaveBeenCalled(); + expect(ormPrRMock.getProjectRolesByProject).not.toHaveBeenCalled(); + expect(ormRMock.getRole).not.toHaveBeenCalled(); + expect(ormPU.getUsersFor).not.toHaveBeenCalled(); + + utilMock.checkYearPermissionProject.mockReset(); +}); + +test("Can modify projects", async () => { + const req = getMockReq(); + + req.body = { + sessionkey: "key", + id: 0, + name: "project-1", + partner: "new-partner", + start: new Date(Date.now()), + end: new Date(Date.now() + 1000), + roles: { + roles: [ + { name: "dev", positions: 101 }, + { name: "frontend", positions: 0 }, + { name: "backend", positions: 12 }, + ], + }, + description: "The old partner sucked", + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(project.modProject(req)).resolves.toStrictEqual({ + description: req.body.description, + start_date: req.body.start.toString(), + end_date: req.body.end.toString(), + partner: req.body.partner, + name: req.body.name, + id: req.body.id, + osoc_id: projects[0].osoc_id, + roles: [ + { + name: "dev", + positions: 3, + }, + { + name: "frontend", + positions: 7, + }, + { + name: "procrastinator", + positions: 7, + }, + ], + coaches: [{ login_user: loginuser, project_user_id: 0 }], + }); + expectCall(reqMock.parseUpdateProjectRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.isValidID).toHaveBeenCalledTimes(1); + expectCall(ormPrMock.updateProject, { + projectId: req.body.id, + name: req.body.name, + partner: req.body.partner, + startDate: req.body.start, + endDate: req.body.end, + osocId: req.body.osocId, + description: req.body.description, + }); + expect(ormRMock.getRole).toHaveBeenCalledTimes( + projectroles.filter((x) => x.project_id == 0).length + ); + expectCall(ormPrRMock.updateProjectRole, { + projectRoleId: 0, + projectId: req.body.id, + roleId: roles[0].role_id, + positions: req.body.roles.roles[0].positions, + }); + expectCall(ormPrRMock.deleteProjectRole, 2); + expectCall(ormPrRMock.getProjectRolesByProject, req.body.id); + + utilMock.checkYearPermissionProject.mockReset(); + ormJMock.getJobApplication.mockReset(); +}); + +test("Can't modify projects (role failure)", async () => { + ormRMock.getRole.mockResolvedValue(null); + const req = getMockReq(); + + req.body = { + sessionkey: "key", + id: 0, + name: "project-1", + partner: "new-partner", + start: new Date(Date.now()), + end: new Date(Date.now() + 1000), + roles: { + roles: [], + }, + description: "The old partner sucked", + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(project.modProject(req)).rejects.toStrictEqual(undefined); + expectCall(reqMock.parseUpdateProjectRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.isValidID).toHaveBeenCalledTimes(1); + expectCall(ormPrMock.updateProject, { + projectId: req.body.id, + name: req.body.name, + partner: req.body.partner, + startDate: req.body.start, + endDate: req.body.end, + osocId: req.body.osocId, + description: req.body.description, + }); + expect(ormRMock.getRole).toHaveBeenCalledTimes(1); + expect(ormPrRMock.updateProjectRole).not.toHaveBeenCalled(); + expect(ormPrRMock.deleteProjectRole).not.toHaveBeenCalled(); + expect(ormPrRMock.getProjectRolesByProject).toHaveBeenCalledTimes(1); + + utilMock.checkYearPermissionProject.mockReset(); + ormJMock.getJobApplication.mockReset(); +}); + +test("Can delete projects", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + await expect(project.deleteProject(req)).resolves.toStrictEqual({}); + expectCall(reqMock.parseDeleteProjectRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.isValidID).toHaveBeenCalledTimes(1); + expectCall(ormPrMock.deleteProjectFromDB, 0); + + utilMock.checkYearPermissionProject.mockReset(); +}); + +test("Can get free spots for project role", async () => { + await expect(project.getFreeSpotsFor("dev", 0)).resolves.toStrictEqual({ + role_id: 0, + project_role_id: 0, + count: 2, + }); + expectCall(ormPrRMock.getProjectRolesByProject, 0); + expect(ormRMock.getRole).toHaveBeenCalledTimes(3); + expectCall(ormPrRole.getNumberOfFreePositions, 0); +}); + +test("Can't get free spots for nonexistent project role", async () => { + await expect(project.getFreeSpotsFor("george", 0)).rejects.toStrictEqual( + undefined + ); + expectCall(ormPrRMock.getProjectRolesByProject, 0); + expect(ormRMock.getRole).toHaveBeenCalledTimes(3); + expect(ormPrRMock.getNumberOfFreePositions).not.toHaveBeenCalled(); +}); + +test("Can create a new project role", async () => { + await expect( + project.createProjectRoleFor(0, roles[1].name) + ).resolves.toStrictEqual({ count: 1, project_role_id: 0 }); + expectCall(ormRMock.getRolesByName, roles[1].name); + expectCall(ormPrRMock.createProjectRole, { + projectId: 0, + roleId: 1, + positions: 1, + }); +}); + +test("Can't create a project role for a nonexistent role", async () => { + await expect( + project.createProjectRoleFor(0, "george") + ).rejects.toStrictEqual({ + http: 409, + reason: "That role doesn't exist.", + }); + expectCall(ormRMock.getRolesByName, "george"); + expect(ormPrRMock.createProjectRole).not.toHaveBeenCalled(); +}); + +test("Can un-assign coaches", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + loginUserId: 0, + }; + + // await project.unAssignCoach(req); + await expect(project.unAssignCoach(req)).resolves.toStrictEqual({}); + expectCall(reqMock.parseRemoveCoachRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expectCall(ormPUMock.getUsersFor, 0); + expectCall(ormPUMock.deleteProjectUser, { + loginUserId: req.body.loginUserId, + projectId: req.body.id, + }); +}); + +test("Can't un-assign coaches (invalid id)", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + loginUserId: 7, + }; + + await expect(project.unAssignCoach(req)).rejects.toStrictEqual({ + http: 400, + reason: "The coach with ID 7 is not assigned to project 0", + }); + expectCall(reqMock.parseRemoveCoachRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expectCall(ormPUMock.getUsersFor, 0); + expect(ormPUMock.deleteProjectUser).not.toHaveBeenCalled(); +}); + +test("Can assign coaches", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + loginUserId: 7, + }; + + await expect(project.assignCoach(req)).resolves.toStrictEqual({ + project_user_id: 0, + login_user_id: 7, + project_id: 0, + }); + expectCall(reqMock.parseAssignCoachRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expectCall(ormPUMock.getUsersFor, 0); + expectCall(ormPUMock.createProjectUser, { projectId: 0, loginUserId: 7 }); +}); + +test("Can't assign coaches (already assigned)", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + loginUserId: 0, + }; + + await expect(project.assignCoach(req)).rejects.toStrictEqual({ + http: 400, + reason: "The coach with ID 0 is already assigned to project 0", + }); + expectCall(reqMock.parseAssignCoachRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expectCall(ormPUMock.getUsersFor, 0); + expect(ormPUMock.createProjectUser).not.toHaveBeenCalled(); +}); + +test("Can un-assign students", async () => { + ormEvMock.getEvaluationByPartiesFor.mockResolvedValue([evals[0]]); + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + studentId: 0, + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + await expect(project.unAssignStudent(req)).resolves.toStrictEqual({}); + expectCall(reqMock.parseRemoveAssigneeRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expectCall(ormCMock.contractsForStudent, req.body.studentId); + expect(ormEvMock.getEvaluationByPartiesFor).toHaveBeenCalledTimes(2); + expect(ormEvMock.updateEvaluationForStudent).toHaveBeenCalledTimes(2); + expect(ormCMock.removeContract).toHaveBeenCalledTimes(2); + + utilMock.checkYearPermissionProject.mockReset(); +}); + +test("Can't un-assign students (no contracts)", async () => { + ormCMock.contractsForStudent.mockResolvedValue([]); + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + studentId: 0, + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + await expect(project.unAssignStudent(req)).rejects.toStrictEqual({ + http: 400, + reason: "The student with ID 0 is not assigned to project 0", + }); + expectCall(reqMock.parseRemoveAssigneeRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expectCall(ormCMock.contractsForStudent, req.body.studentId); + expect(ormEvMock.getEvaluationByPartiesFor).not.toHaveBeenCalled(); + expect(ormEvMock.updateEvaluationForStudent).not.toHaveBeenCalled(); + expect(ormCMock.removeContract).not.toHaveBeenCalled(); + + utilMock.checkYearPermissionProject.mockReset(); +}); + +test("Can assign students", async () => { + const req = getMockReq(); + req.body = { + studentId: 0, + id: 0, + sessionkey: "key", + role: "dev", + jobApplicationId: 0, + }; + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(project.assignStudent(req)).resolves.toStrictEqual({ + drafted: true, + role: "dev", + }); + expectCall(reqMock.parseDraftStudentRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(ormOMock.getLatestOsoc).toHaveBeenCalledTimes(1); + expectCall(ormCMock.contractsForStudent, req.body.studentId); + expectCall(ormCMock.createContract, { + studentId: req.body.studentId, + projectRoleId: 0, + loginUserId: 0, + contractStatus: "DRAFT", + }); + + ormJMock.getJobApplication.mockReset(); +}); + +test("Can't assign students (no places)", async () => { + ormPrRMock.getNumberOfFreePositions.mockResolvedValue(0); + const req = getMockReq(); + req.body = { + studentId: 0, + id: 0, + sessionkey: "key", + role: "dev", + jobApplicationId: 0, + }; + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(project.assignStudent(req)).rejects.toStrictEqual({ + http: 409, + reason: "There are no more free spaces for that role", + }); + expectCall(reqMock.parseDraftStudentRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(ormOMock.getLatestOsoc).toHaveBeenCalledTimes(1); + expectCall(ormCMock.contractsForStudent, req.body.studentId); + expect(ormCMock.createContract).not.toHaveBeenCalled(); + + ormJMock.getJobApplication.mockReset(); +}); + +test("Can't assign students (no such role)", async () => { + ormPrRMock.getProjectRolesByProject.mockResolvedValue([]); + const req = getMockReq(); + req.body = { + studentId: 0, + id: 0, + sessionkey: "key", + role: "dev", + jobApplicationId: 0, + }; + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(project.assignStudent(req)).rejects.toStrictEqual({ + http: 404, + reason: "That role doesn't exist", + }); + expectCall(reqMock.parseDraftStudentRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(ormOMock.getLatestOsoc).toHaveBeenCalledTimes(1); + expectCall(ormCMock.contractsForStudent, req.body.studentId); + expect(ormCMock.createContract).not.toHaveBeenCalled(); + + ormJMock.getJobApplication.mockReset(); +}); + +test("Can't assign students (already used)", async () => { + ormOMock.getLatestOsoc.mockResolvedValue({ + osoc_id: studcontr[0].project_role.project.osoc_id, + year: 2022, + }); + const req = getMockReq(); + req.body = { + studentId: 0, + id: 0, + sessionkey: "key", + role: "dev", + jobApplicationId: 0, + }; + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(project.assignStudent(req)).rejects.toStrictEqual({ + http: 409, + reason: "This student does already have a contract", + }); + expectCall(reqMock.parseDraftStudentRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(ormOMock.getLatestOsoc).toHaveBeenCalledTimes(1); + expectCall(ormCMock.contractsForStudent, req.body.studentId); + expect(ormCMock.createContract).not.toHaveBeenCalled(); + + ormJMock.getJobApplication.mockReset(); +}); + +test("Can filter projects", async () => { + ormCMock.contractsByProject.mockResolvedValue([]); + ormPUMock.getUsersFor.mockResolvedValue([]); + const req = getMockReq(); + req.body = { sessionkey: "key" }; + + const res = projects.map((x) => ({ + id: x.project_id, + name: x.name, + description: x.description, + partner: x.partner, + start_date: x.start_date.toString(), + end_date: x.end_date.toString(), + osoc_id: x.osoc_id, + contracts: [], + coaches: [], + roles: projectroles + .filter((y) => y.project_id == x.project_id) + .map((y) => ({ + name: roles[y.role_id].name, + positions: y.positions, + })), + })); + + await expect(project.filterProjects(req)).resolves.toStrictEqual({ + data: res, + pagination: { count: projects.length, page: 0 }, + }); + expectCall(reqMock.parseFilterProjectsRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expect(ormOMock.getLatestOsoc).toHaveBeenCalledTimes(1); + expect(ormPr.filterProjects).toHaveBeenCalledTimes(1); + expect(ormPr.filterProjects).toHaveBeenCalledWith( + { + currentPage: undefined, + pageSize: undefined, + }, + undefined, + undefined, + undefined, + 2022, + undefined, + undefined, + 0 + ); + expect(ormCMock.contractsByProject).toHaveBeenCalledTimes(projects.length); + expect(ormPU.getUsersFor).toHaveBeenCalledTimes(projects.length); +}); + +test("Can filter projects (with osoc year)", async () => { + ormCMock.contractsByProject.mockResolvedValue([]); + ormPUMock.getUsersFor.mockResolvedValue([]); + const req = getMockReq(); + req.body = { sessionkey: "key", osocYear: 2021 }; + + const res = projects.map((x) => ({ + id: x.project_id, + name: x.name, + description: x.description, + partner: x.partner, + start_date: x.start_date.toString(), + end_date: x.end_date.toString(), + osoc_id: x.osoc_id, + contracts: [], + coaches: [], + roles: projectroles + .filter((y) => y.project_id == x.project_id) + .map((y) => ({ + name: roles[y.role_id].name, + positions: y.positions, + })), + })); + + await expect(project.filterProjects(req)).resolves.toStrictEqual({ + data: res, + pagination: { count: projects.length, page: 0 }, + }); + expectCall(reqMock.parseFilterProjectsRequest, req); + expectCall(utilMock.checkSessionKey, req.body); + expect(ormOMock.getLatestOsoc).not.toHaveBeenCalled(); + expect(ormPr.filterProjects).toHaveBeenCalledTimes(1); + expect(ormPr.filterProjects).toHaveBeenCalledWith( + { + currentPage: undefined, + pageSize: undefined, + }, + undefined, + undefined, + undefined, + 2021, + undefined, + undefined, + 0 + ); + expect(ormCMock.contractsByProject).toHaveBeenCalledTimes(projects.length); + expect(ormPU.getUsersFor).toHaveBeenCalledTimes(projects.length); +}); + +test("Can modify a student on a project", async () => { + ormPrRMock.getNumberOfFreePositions.mockResolvedValue(0); + + const req = getMockReq(); + req.body = { + sessionkey: "key", + id: 0, + studentId: 0, + role: "frontend", + }; + + reqMock.parseUpdateProjectRequest.mockResolvedValue({ + sessionkey: "key", + id: 0, + name: "name", + addCoaches: { + coaches: [0], + }, + removeCoaches: { + coaches: [0], + }, + }); + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + const start = new Date(); + const end = new Date(); + + ormPrMock.updateProject.mockImplementation((v) => + Promise.resolve({ + project_id: v.projectId, + name: orDefault(v.name, "name"), + osoc_id: orDefault(v.osocId, 0), + partner: orDefault(v.partner, "partner"), + description: orDefault(v.description, null), + start_date: orDefault(v.startDate, start), + end_date: orDefault(v.endDate, end), + }) + ); + + ormPrRMock.getProjectRoleNamesByProject.mockResolvedValue([]); + ormPrRMock.getProjectRolesByProject.mockResolvedValue([]); + + ormPUMock.createProjectUser.mockResolvedValue({ + project_user_id: 0, + login_user_id: 0, + project_id: 0, + }); + + ormPUMock.deleteProjectUser.mockResolvedValue({ + count: 1, + }); + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormPUMock.getUsersFor.mockResolvedValue([]); + + await expect(project.modProject(req)).resolves.toStrictEqual({ + id: 0, + name: "name", + partner: "partner", + start_date: start.toString(), + end_date: end.toString(), + osoc_id: 0, + roles: [], + description: null, + coaches: [], + }); + + utilMock.checkYearPermissionProject.mockReset(); + reqMock.parseUpdateProjectRequest.mockReset(); + ormPrRMock.getProjectRoleNamesByProject.mockReset(); + ormPrRMock.getProjectRolesByProject.mockReset(); + ormPUMock.createProjectUser.mockReset(); + ormPUMock.deleteProjectUser.mockReset(); + ormPUMock.getUsersFor.mockReset(); + ormPrMock.updateProject.mockReset(); + ormJMock.getJobApplication.mockReset(); +}); + +test("Can filter projects (with osoc year)", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + projectNameFilter: "project", + osocYear: 2022, + }; + + reqMock.parseFilterProjectsRequest.mockResolvedValue({ + sessionkey: "key", + projectNameFilter: "project", + clientNameFilter: undefined, + fullyAssignedFilter: undefined, + osocYear: 2022, + projectNameSort: undefined, + clientNameSort: undefined, + currentPage: 0, + pageSize: 1, + }); + + const start = new Date(); + const end = new Date(); + + ormPrMock.filterProjects.mockResolvedValue({ + pagination: { + page: 0, + count: 1, + }, + data: [ + { + project_id: 0, + osoc_id: 0, + name: "name", + partner: "partner", + description: null, + start_date: start, + end_date: end, + project_role: [ + { + positions: 3, + role: { + name: "Front-end developer", + }, + }, + { + positions: 5, + role: { + name: "Back-end developer", + }, + }, + ], + project_user: [ + { + login_user: { + login_user_id: 1, + is_coach: true, + }, + }, + { + login_user: { + login_user_id: 2, + is_coach: true, + }, + }, + ], + }, + ], + }); + + ormPrRMock.getProjectRolesByProject.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 3, + }, + { + project_role_id: 1, + project_id: 0, + role_id: 1, + positions: 5, + }, + ]); + + ormRMock.getRole.mockResolvedValueOnce({ + role_id: 0, + name: "Front-end developer", + }); + + ormRMock.getRole.mockResolvedValueOnce({ + role_id: 1, + name: "Back-end developer", + }); + + ormCMock.contractsByProject.mockResolvedValue([ + { + contract_id: 0, + contract_status: contract_status_enum.APPROVED, + student: { + student_id: 0, + gender: "Male", + pronouns: null, + phone_number: "0461719074", + nickname: null, + alumni: false, + person: { + name: "name", + person_id: 0, + email: "mail@mail.com", + github: null, + github_id: null, + }, + }, + project_role: { + project_id: 0, + role: { + name: "Front-end developer", + }, + project_role_id: 0, + role_id: 0, + positions: 3, + }, + login_user: null, + }, + ]); + + ormPUMock.getUsersFor.mockResolvedValue([]); + + await expect(project.filterProjects(req)).resolves.toStrictEqual({ + data: [ + { + osoc_id: 0, + name: "name", + partner: "partner", + description: null, + start_date: start.toString(), + end_date: end.toString(), + id: 0, + coaches: [], + roles: [ + { + positions: 3, + name: "Front-end developer", + }, + { + positions: 5, + name: "Back-end developer", + }, + ], + contracts: [ + { + contract_id: 0, + contract_status: contract_status_enum.APPROVED, + student: { + evaluation: undefined, + evaluations: undefined, + jobApplication: undefined, + roles: undefined, + student: { + student_id: 0, + gender: "Male", + pronouns: null, + phone_number: "0461719074", + nickname: null, + alumni: false, + person_id: undefined, + person: { + name: "name", + person_id: 0, + email: "mail@mail.com", + github: null, + github_id: null, + }, + }, + }, + project_role: { + project_id: 0, + role: { + name: "Front-end developer", + }, + project_role_id: 0, + role_id: 0, + positions: 3, + }, + login_user: null, + }, + ], + }, + ], + pagination: { count: 1, page: 0 }, + }); + + reqMock.parseFilterProjectsRequest.mockReset(); + ormPrMock.filterProjects.mockReset(); + ormPrRMock.getProjectRolesByProject.mockReset(); + ormRMock.getRole.mockReset(); + ormCMock.contractsByProject.mockReset(); + ormPUMock.getUsersFor.mockReset(); +}); + +test("No filtered projects", async () => { + const req = getMockReq(); + req.body = { sessionkey: "key", projectNameFilter: "project" }; + + ormOMock.getLatestOsoc.mockResolvedValue(null); + + reqMock.parseFilterProjectsRequest.mockResolvedValue({ + sessionkey: "key", + projectNameFilter: "project", + clientNameFilter: undefined, + fullyAssignedFilter: undefined, + osocYear: undefined, + projectNameSort: undefined, + clientNameSort: undefined, + currentPage: 0, + pageSize: 1, + }); + + ormPrMock.filterProjects.mockResolvedValue({ + pagination: { + page: 0, + count: 1, + }, + data: [], + }); + + await expect(project.filterProjects(req)).resolves.toStrictEqual({ + data: [], + pagination: { count: 1, page: 0 }, + }); + + reqMock.parseFilterProjectsRequest.mockReset(); + ormPrMock.filterProjects.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("No role found in filterProjects", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + projectNameFilter: "project", + osocYear: 2022, + }; + + reqMock.parseFilterProjectsRequest.mockResolvedValue({ + sessionkey: "key", + projectNameFilter: "project", + clientNameFilter: undefined, + fullyAssignedFilter: undefined, + osocYear: 2022, + projectNameSort: undefined, + clientNameSort: undefined, + currentPage: 0, + pageSize: 1, + }); + + ormPrMock.filterProjects.mockResolvedValue({ + pagination: { + page: 0, + count: 1, + }, + data: [ + { + project_id: 0, + osoc_id: 0, + name: "name", + partner: "partner", + description: null, + start_date: new Date( + "Mon Jan 12 1970 14:46:40 GMT+0100 (Central European Standard Time)" + ), + end_date: new Date( + "Sun Apr 26 1970 18:46:40 GMT+0100 (Central European Standard Time)" + ), + project_role: [ + { + positions: 3, + role: { + name: "Front-end developer", + }, + }, + { + positions: 5, + role: { + name: "Back-end developer", + }, + }, + ], + project_user: [ + { + login_user: { + login_user_id: 1, + is_coach: true, + }, + }, + { + login_user: { + login_user_id: 2, + is_coach: true, + }, + }, + ], + }, + ], + }); + + ormPrRMock.getProjectRolesByProject.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 3, + }, + { + project_role_id: 1, + project_id: 0, + role_id: 1, + positions: 5, + }, + ]); + + ormRMock.getRole.mockResolvedValueOnce({ + role_id: 0, + name: "Front-end developer", + }); + + ormRMock.getRole.mockResolvedValueOnce(null); + + await expect(project.filterProjects(req)).rejects.toBe( + errors.cookNoDataError() + ); + + reqMock.parseFilterProjectsRequest.mockReset(); + ormPrMock.filterProjects.mockReset(); + ormPrRMock.getProjectRolesByProject.mockReset(); + ormRMock.getRole.mockReset(); +}); + +test("Contract.student is null in filterProjects", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "key", + projectNameFilter: "project", + osocYear: 2022, + }; + + reqMock.parseFilterProjectsRequest.mockResolvedValue({ + sessionkey: "key", + projectNameFilter: "project", + clientNameFilter: undefined, + fullyAssignedFilter: undefined, + osocYear: 2022, + projectNameSort: undefined, + clientNameSort: undefined, + currentPage: 0, + pageSize: 1, + }); + + const start = new Date(); + const end = new Date(); + + ormPrMock.filterProjects.mockResolvedValue({ + pagination: { + page: 0, + count: 1, + }, + data: [ + { + project_id: 0, + osoc_id: 0, + name: "name", + partner: "partner", + description: null, + start_date: start, + end_date: end, + project_role: [ + { + positions: 3, + role: { + name: "Front-end developer", + }, + }, + { + positions: 5, + role: { + name: "Back-end developer", + }, + }, + ], + project_user: [ + { + login_user: { + login_user_id: 1, + is_coach: true, + }, + }, + { + login_user: { + login_user_id: 2, + is_coach: true, + }, + }, + ], + }, + ], + }); + + ormPrRMock.getProjectRolesByProject.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 3, + }, + { + project_role_id: 1, + project_id: 0, + role_id: 1, + positions: 5, + }, + ]); + + ormRMock.getRole.mockResolvedValueOnce({ + role_id: 0, + name: "Front-end developer", + }); + + ormRMock.getRole.mockResolvedValueOnce({ + role_id: 1, + name: "Back-end developer", + }); + + ormCMock.contractsByProject.mockResolvedValue([ + { + contract_id: 0, + contract_status: contract_status_enum.APPROVED, + student: null, + project_role: { + project_id: 0, + role: { + name: "Front-end developer", + }, + project_role_id: 0, + role_id: 0, + positions: 3, + }, + login_user: null, + }, + ]); + + ormPUMock.getUsersFor.mockResolvedValue([]); + + await expect(project.filterProjects(req)).resolves.toStrictEqual({ + data: [ + { + osoc_id: 0, + name: "name", + partner: "partner", + description: null, + start_date: start.toString(), + end_date: end.toString(), + id: 0, + coaches: [], + roles: [ + { + positions: 3, + name: "Front-end developer", + }, + { + positions: 5, + name: "Back-end developer", + }, + ], + contracts: [ + { + contract_id: 0, + contract_status: contract_status_enum.APPROVED, + student: { + evaluation: undefined, + evaluations: undefined, + jobApplication: undefined, + roles: undefined, + student: null, + }, + project_role: { + project_id: 0, + role: { + name: "Front-end developer", + }, + project_role_id: 0, + role_id: 0, + positions: 3, + }, + login_user: null, + }, + ], + }, + ], + pagination: { count: 1, page: 0 }, + }); + + await expect(project.listProjects(req)).resolves.toStrictEqual({ + data: [ + { + osoc_id: 0, + name: "name", + partner: "partner", + description: null, + start_date: start.toString(), + end_date: end.toString(), + id: 0, + coaches: [], + roles: [ + { + positions: 3, + name: "dev", + }, + { + positions: 5, + name: "backend", + }, + ], + contracts: [ + { + contract_id: 0, + contract_status: contract_status_enum.APPROVED, + student: { + evaluation: undefined, + evaluations: undefined, + jobApplication: undefined, + roles: undefined, + student: null, + }, + project_role: { + project_id: 0, + role: { + name: "Front-end developer", + }, + project_role_id: 0, + role_id: 0, + positions: 3, + }, + login_user: null, + }, + ], + }, + ], + pagination: { count: 1, page: 0 }, + }); + + reqMock.parseFilterProjectsRequest.mockReset(); + ormPrMock.filterProjects.mockReset(); + ormPrRMock.getProjectRolesByProject.mockReset(); + ormRMock.getRole.mockReset(); + ormCMock.contractsByProject.mockReset(); + ormPUMock.getUsersFor.mockReset(); +}); + +test("Can get free spots for project role", async () => { + ormPrRMock.getProjectRolesByProject.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 3, + }, + ]); + + ormRMock.getRole.mockResolvedValue({ + role_id: 0, + name: "Developer", + }); + + ormPrRMock.getNumberOfFreePositions.mockResolvedValue(3); + + await expect( + project.getFreeSpotsFor("Developer", 0) + ).resolves.toStrictEqual({ + project_role_id: 0, + role_id: 0, + count: 3, + }); + + ormPrRMock.getProjectRolesByProject.mockReset(); + ormRMock.getRole.mockReset(); + ormPrRMock.getNumberOfFreePositions.mockReset(); +}); + +test("Can't get free spots for project role", async () => { + ormPrRMock.getProjectRolesByProject.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 3, + }, + ]); + + ormRMock.getRole.mockResolvedValue({ + role_id: 0, + name: "Developer", + }); + + await expect(project.getFreeSpotsFor("dev", 0)).rejects.toBe( + errors.cookArgumentError() + ); + + ormPrRMock.getProjectRolesByProject.mockReset(); + ormRMock.getRole.mockReset(); +}); + +test("Can't get free spots for project role (number of free spots is null)", async () => { + ormPrRMock.getProjectRolesByProject.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 3, + }, + ]); + + ormRMock.getRole.mockResolvedValue({ + role_id: 0, + name: "Developer", + }); + + ormPrRMock.getNumberOfFreePositions.mockResolvedValue(null); + + await expect(project.getFreeSpotsFor("Developer", 0)).rejects.toBe( + errors.cookArgumentError() + ); + + ormPrRMock.getProjectRolesByProject.mockReset(); + ormRMock.getRole.mockReset(); + ormPrRMock.getNumberOfFreePositions.mockReset(); +}); + +test("Can't get free spots for project role (number of free spots is null)", async () => { + ormPrRMock.getProjectRolesByProject.mockResolvedValue([ + { + project_role_id: 0, + project_id: 0, + role_id: 0, + positions: 3, + }, + ]); + + ormRMock.getRole.mockResolvedValue({ + role_id: 0, + name: "Developer", + }); + + ormPrRMock.getNumberOfFreePositions.mockResolvedValue(null); + + await expect(project.getFreeSpotsFor("Developer", 0)).rejects.toBe( + errors.cookArgumentError() + ); + + ormPrRMock.getProjectRolesByProject.mockReset(); + ormRMock.getRole.mockReset(); + ormPrRMock.getNumberOfFreePositions.mockReset(); +}); + +test("Can't create new projects", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "some-key", + osocId: 0, + name: "Operation Ivy", + partner: "US Goverment", + description: + "Let's build a thermonuclear warhead! What could go wrong?", + start: new Date("January 31, 1950"), + end: new Date("November 15, 1952 23:30:00.0"), + roles: { + roles: [ + { name: "dev", positions: 8 }, + { name: "nuclear bomb engineer", positions: 2 }, + ], + }, + coaches: { + coaches: [0], + }, + }; + + ormLUMock.getOsocYearsForLoginUser.mockResolvedValue([2022]); + + ormOMock.getOsocById.mockResolvedValue({ + osoc_id: 0, + year: 2022, + }); + + ormOMock.getLatestOsoc.mockResolvedValue(null); + + await expect(project.createProject(req)).rejects.toBe( + errors.cookWrongOsocYear() + ); + + ormLUMock.getOsocYearsForLoginUser.mockReset(); + ormOMock.getOsocById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("Assign student, project year not equal to latest osoc year", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "some-key", + osocId: 0, + name: "Operation Ivy", + partner: "US Goverment", + description: + "Let's build a thermonuclear warhead! What could go wrong?", + start: new Date("January 31, 1950"), + end: new Date("November 15, 1952 23:30:00.0"), + roles: { + roles: [ + { name: "dev", positions: 8 }, + { name: "nuclear bomb engineer", positions: 2 }, + ], + }, + coaches: { + coaches: [0], + }, + }; + + reqMock.parseDraftStudentRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + studentId: 0, + role: "dev", + jobApplicationId: 0, + }); + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormOMock.getLatestOsoc.mockResolvedValue({ + osoc_id: 1, + year: 2023, + }); + + ormPrMock.getProjectById.mockImplementation(() => { + return Promise.resolve(projects2[0]); + }); + + await expect(project.assignStudent(req)).rejects.toBe( + errors.cookWrongOsocYear() + ); + + reqMock.parseDraftStudentRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); + ormJMock.getJobApplication.mockReset(); +}); + +test("Assign student, project is null", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "some-key", + osocId: 0, + name: "Operation Ivy", + partner: "US Goverment", + description: + "Let's build a thermonuclear warhead! What could go wrong?", + start: new Date("January 31, 1950"), + end: new Date("November 15, 1952 23:30:00.0"), + roles: { + roles: [ + { name: "dev", positions: 8 }, + { name: "nuclear bomb engineer", positions: 2 }, + ], + }, + coaches: { + coaches: [0], + }, + }; + + reqMock.parseDraftStudentRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + studentId: 0, + role: "dev", + jobApplicationId: 0, + }); + + ormOMock.getLatestOsoc.mockResolvedValue({ + osoc_id: 1, + year: 2023, + }); + + ormPrMock.getProjectById.mockResolvedValue(null); + + await expect(project.assignStudent(req)).rejects.toBe( + errors.cookInvalidID() + ); + + reqMock.parseDraftStudentRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("UnAssign student, project is null", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "some-key", + student: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseRemoveAssigneeRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + studentId: 0, + }); + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + ormOMock.getLatestOsoc.mockResolvedValue({ + osoc_id: 1, + year: 2023, + }); + + ormPrMock.getProjectById.mockResolvedValue(null); + + await expect(project.unAssignStudent(req)).rejects.toBe( + errors.cookInvalidID() + ); + + reqMock.parseRemoveAssigneeRequest.mockReset(); + utilMock.checkYearPermissionProject.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("UnAssign student, latest osoc is null", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "some-key", + student: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseRemoveAssigneeRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + studentId: 0, + }); + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + ormOMock.getLatestOsoc.mockResolvedValue(null); + + ormPrMock.getProjectById.mockImplementation(() => { + return Promise.resolve(projects2[0]); + }); + + await expect(project.unAssignStudent(req)).rejects.toBe( + errors.cookInvalidID() + ); + + reqMock.parseRemoveAssigneeRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); + utilMock.checkYearPermissionProject.mockReset(); +}); + +test("Assign coach, project is null", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "some-key", + loginUserId: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseAssignCoachRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + loginUserId: 0, + }); + + ormOMock.getLatestOsoc.mockResolvedValue({ + osoc_id: 1, + year: 2023, + }); + + ormPrMock.getProjectById.mockResolvedValue(null); + + await expect(project.assignCoach(req)).rejects.toBe(errors.cookInvalidID()); + + reqMock.parseAssignCoachRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("Assign coach, latest osoc is null", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "some-key", + loginUserId: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseAssignCoachRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + loginUserId: 0, + }); + + ormOMock.getLatestOsoc.mockResolvedValue(null); + + ormPrMock.getProjectById.mockImplementation(() => { + return Promise.resolve(projects2[0]); + }); + + await expect(project.assignCoach(req)).rejects.toBe(errors.cookInvalidID()); + + reqMock.parseAssignCoachRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("UnAssign coach, project is null", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "some-key", + loginUserId: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseRemoveCoachRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + loginUserId: 0, + }); + + ormOMock.getLatestOsoc.mockResolvedValue({ + osoc_id: 1, + year: 2023, + }); + + ormPrMock.getProjectById.mockResolvedValue(null); + + await expect(project.unAssignCoach(req)).rejects.toBe( + errors.cookInvalidID() + ); + + reqMock.parseRemoveCoachRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("UnAssign coach, latest osoc is null", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "some-key", + loginUserId: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseRemoveCoachRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + loginUserId: 0, + }); + + ormOMock.getLatestOsoc.mockResolvedValue(null); + + ormPrMock.getProjectById.mockImplementation(() => { + return Promise.resolve(projects2[0]); + }); + + await expect(project.unAssignCoach(req)).rejects.toBe( + errors.cookInvalidID() + ); + + reqMock.parseRemoveCoachRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("Modify projects, latest osoc is null", async () => { + const req = getMockReq(); + + req.body = { + sessionkey: "key", + id: 0, + name: "project-1", + partner: "new-partner", + start: new Date(Date.now()), + end: new Date(Date.now() + 1000), + roles: { + roles: [ + { name: "dev", positions: 101 }, + { name: "frontend", positions: 0 }, + { name: "backend", positions: 12 }, + ], + }, + description: "The old partner sucked", + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormOMock.getLatestOsoc.mockResolvedValue(null); + + await expect(project.modProject(req)).rejects.toBe( + errors.cookWrongOsocYear() + ); + + utilMock.checkYearPermissionProject.mockReset(); + ormJMock.getJobApplication.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("Modify projects, job application is null", async () => { + const req = getMockReq(); + + req.body = { + sessionkey: "key", + id: 0, + name: "project-1", + partner: "new-partner", + start: new Date(Date.now()), + end: new Date(Date.now() + 1000), + roles: { + roles: [ + { name: "dev", positions: 101 }, + { name: "frontend", positions: 0 }, + { name: "backend", positions: 12 }, + ], + }, + description: "The old partner sucked", + }; + + utilMock.checkYearPermissionProject.mockImplementation((v) => + Promise.resolve(v) + ); + + ormJMock.getJobApplication.mockResolvedValue(null); + + ormOMock.getLatestOsoc.mockResolvedValue(null); + + await expect(project.modProject(req)).rejects.toBe(errors.cookInvalidID()); + + utilMock.checkYearPermissionProject.mockReset(); + ormJMock.getJobApplication.mockReset(); + ormOMock.getLatestOsoc.mockReset(); +}); + +test("Assign student, project year not equal to job application year", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "some-key", + osocId: 0, + name: "Operation Ivy", + partner: "US Goverment", + description: + "Let's build a thermonuclear warhead! What could go wrong?", + start: new Date("January 31, 1950"), + end: new Date("November 15, 1952 23:30:00.0"), + roles: { + roles: [ + { name: "dev", positions: 8 }, + { name: "nuclear bomb engineer", positions: 2 }, + ], + }, + coaches: { + coaches: [0], + }, + }; + + reqMock.parseDraftStudentRequest.mockResolvedValue({ + id: 0, + sessionkey: "some-key", + studentId: 0, + role: "dev", + jobApplicationId: 0, + }); + + ormJMock.getJobApplication.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormOMock.getLatestOsoc.mockResolvedValue({ + osoc_id: 1, + year: 2023, + }); + + ormPrMock.getProjectById.mockImplementation(() => { + return Promise.resolve({ + project_id: 0, + name: "sample project", + osoc_id: 0, + partner: "jefke", + description: null, + start_date: new Date(Date.now()), + end_date: new Date(Date.now()), + osoc: { + osoc_id: 0, + year: 2023, + }, + }); + }); + + await expect(project.assignStudent(req)).rejects.toStrictEqual({ + http: 403, + reason: "Student application and project are from different osoc editions", + }); + + reqMock.parseDraftStudentRequest.mockReset(); + ormPrMock.getProjectById.mockReset(); + ormOMock.getLatestOsoc.mockReset(); + ormJMock.getJobApplication.mockReset(); +}); diff --git a/backend/tests/routes_unit/reset.test.ts b/backend/tests/routes_unit/reset.test.ts new file mode 100644 index 00000000..5f6b979e --- /dev/null +++ b/backend/tests/routes_unit/reset.test.ts @@ -0,0 +1,452 @@ +const setCredMock = jest.fn().mockImplementation(() => { + /* EMPTY */ +}); +const getATMock = jest + .fn() + .mockImplementation(() => Promise.resolve({ token: "token" })); +const createAuthClientMock = jest.fn().mockImplementation(() => ({ + setCredentials: setCredMock, + getAccessToken: getATMock, +})); + +const sendMailMock = jest.fn().mockImplementation(() => Promise.resolve()); +const closeTranspMock = jest.fn().mockImplementation(() => { + /* nothing happens here */ +}); +const createTranspMock = jest.fn().mockImplementation(() => ({ + sendMail: sendMailMock, + close: closeTranspMock, +})); +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { login_user, person } from "@prisma/client"; +import * as config from "../../config.json"; + +// set up mocks for libraries +import * as gapis from "googleapis"; +jest.mock("googleapis", () => ({ + Auth: { + OAuth2Client: createAuthClientMock, + }, +})); +const gapiMock = gapis as jest.Mocked; + +const nodemailer = require("nodemailer"); +jest.mock("nodemailer", () => ({ + createTransport: createTranspMock, +})); +const mailMock = nodemailer as jest.Mocked; + +import * as bcrypt from "bcrypt"; +jest.mock("bcrypt"); +const bcryptMock = bcrypt as jest.Mocked; + +// set up mocks for our files +import * as rq from "../../request"; +jest.mock("../../request"); +const reqMock = rq as jest.Mocked; + +import * as util from "../../utility"; +jest.mock("../../utility"); +const utilMock = util as jest.Mocked; + +import * as ormPR from "../../orm_functions/password_reset"; +jest.mock("../../orm_functions/password_reset"); +const ormPRMock = ormPR as jest.Mocked; + +import * as ormP from "../../orm_functions/person"; +jest.mock("../../orm_functions/person"); +const ormPMock = ormP as jest.Mocked; + +import * as ormLU from "../../orm_functions/login_user"; +jest.mock("../../orm_functions/login_user"); +const ormLUMock = ormLU as jest.Mocked; + +import * as ormSK from "../../orm_functions/session_key"; +jest.mock("../../orm_functions/session_key"); +const ormSKMock = ormSK as jest.Mocked; + +// to test +import * as reset from "../../routes/reset"; + +process.env.GOOGLE_CLIENT_ID = "some_google_client_id"; +process.env.GOOGLE_CLIENT_SECRET = "some_google_client_secret"; +process.env.GOOGLE_REFRESH_TOKEN = "some_google_refresh_token"; + +const user: login_user & { person: person } = { + login_user_id: 0, + person_id: 1231, + password: "old_pass", + is_admin: false, + is_coach: true, + account_status: "ACTIVATED", + person: { + person_id: 1231, + email: "imperson0@mail.com", + github: null, + name: "Person #0", + github_id: null, + }, +}; + +beforeEach(() => { + bcryptMock.hash.mockImplementation((v) => Promise.resolve(v)); + + utilMock.generateKey.mockReturnValue("key"); + + sendMailMock.mockImplementation(() => Promise.resolve()); + closeTranspMock.mockImplementation(() => { + /* nothing happens here */ + }); + createTranspMock.mockImplementation(() => ({ + sendMail: sendMailMock, + close: closeTranspMock, + })); + + setCredMock.mockImplementation(() => { + /* EMPTY */ + }); + getATMock.mockImplementation(() => Promise.resolve({ token: "token" })); + createAuthClientMock.mockImplementation(() => ({ + setCredentials: setCredMock, + getAccessToken: getATMock, + })); + + reqMock.parseRequestResetRequest.mockResolvedValue({ + email: "jeffrey@jan.com", + }); + reqMock.parseCheckResetCodeRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseResetPasswordRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + + ormPMock.getPasswordPersonByEmail.mockResolvedValue({ + login_user: { + login_user_id: 0, + password: "null", + account_status: "PENDING", + is_admin: true, + is_coach: true, + }, + }); + + ormPRMock.createOrUpdateReset.mockImplementation((i, r, v) => + Promise.resolve({ + password_reset_id: 0, + login_user_id: i, + reset_id: r, + valid_until: v, + }) + ); + ormPRMock.findResetByCode.mockImplementation((code) => { + if (code === "valid_code_believe_me_okay?") + return Promise.resolve({ + password_reset_id: 0, + login_user_id: 0, + reset_id: code, + valid_until: new Date(Date.now() + 10000), + }); + if (code === "outdate_code") + return Promise.resolve({ + password_reset_id: 0, + login_user_id: 0, + reset_id: code, + valid_until: new Date(0), + }); + return Promise.resolve(null); + }); + ormPRMock.deleteResetWithResetId.mockImplementation((id) => + Promise.resolve({ + password_reset_id: 0, + login_user_id: 0, + reset_id: id, + valid_until: new Date(Date.now() + 1000), + }) + ); + + ormLUMock.getLoginUserById.mockResolvedValue(user); + ormLUMock.updateLoginUser.mockResolvedValue(user); + + ormSKMock.addSessionKey.mockImplementation((i, k, d) => + Promise.resolve({ + session_key: k, + session_key_id: 0, + valid_until: d, + login_user_id: i, + }) + ); +}); + +afterEach(() => { + bcryptMock.hash.mockReset(); + + utilMock.generateKey.mockReset(); + + sendMailMock.mockReset(); + closeTranspMock.mockReset(); + createTranspMock.mockReset(); + + setCredMock.mockReset(); + getATMock.mockReset(); + createAuthClientMock.mockReset(); + + reqMock.parseRequestResetRequest.mockReset(); + reqMock.parseCheckResetCodeRequest.mockReset(); + reqMock.parseResetPasswordRequest.mockReset(); + + ormPMock.getPasswordPersonByEmail.mockReset(); + + ormPRMock.createOrUpdateReset.mockReset(); + ormPRMock.findResetByCode.mockReset(); + ormPRMock.deleteResetWithResetId.mockReset(); + + ormLUMock.getLoginUserById.mockReset(); + ormLUMock.updateLoginUser.mockReset(); + + ormSKMock.addSessionKey.mockReset(); +}); + +function expectSentMail() { + expect(mailMock.createTransport).toHaveBeenCalledTimes(1); + expect(sendMailMock).toHaveBeenCalledTimes(1); + expect(closeTranspMock).toHaveBeenCalledTimes(1); +} + +function expectSetupGapi() { + expect(createAuthClientMock).toHaveBeenCalledTimes(1); + expect(createAuthClientMock).toHaveBeenCalledWith( + process.env.GOOGLE_CLIENT_ID, + process.env.GOOGLE_CLIENT_SECRET + ); + expectCall(setCredMock, { + refresh_token: process.env.GOOGLE_REFRESH_TOKEN, + }); + expect(gapiMock.Auth.OAuth2Client).toHaveBeenCalled(); +} + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +test("Can send emails (vague)", async () => { + await expect( + reset.sendMail({ + to: "jeff@hotmail.com", + subject: "nothing", + html: "empty", + }) + ).resolves.toBe(undefined); + expectSentMail(); + expectSetupGapi(); +}); + +test("Google can cause emails to fail (v1)", async () => { + getATMock.mockResolvedValue(null); + await expect( + reset.sendMail({ + to: "jeff@hotmail.com", + subject: "nothing", + html: "empty", + }) + ).rejects.toStrictEqual(config.apiErrors.reset.sendEmail); + expectSetupGapi(); + expect(createTranspMock).not.toHaveBeenCalled(); + expect(sendMailMock).not.toHaveBeenCalled(); + expect(closeTranspMock).not.toHaveBeenCalled(); +}); + +test("Google can cause emails to fail (v2)", async () => { + getATMock.mockResolvedValue({ token: null }); + await expect( + reset.sendMail({ + to: "jeff@hotmail.com", + subject: "nothing", + html: "empty", + }) + ).rejects.toStrictEqual(config.apiErrors.reset.sendEmail); + expectSetupGapi(); + expect(createTranspMock).not.toHaveBeenCalled(); + expect(sendMailMock).not.toHaveBeenCalled(); + expect(closeTranspMock).not.toHaveBeenCalled(); +}); + +test("Nodemailer can cause emails to fail", async () => { + sendMailMock.mockRejectedValue({ error: "something i guess" }); + await expect( + reset.sendMail({ + to: "jeff@hotmail.com", + subject: "nothing", + html: "empty", + }) + ).rejects.toStrictEqual(config.apiErrors.reset.sendEmail); + expectSetupGapi(); + expect(mailMock.createTransport).toHaveBeenCalledTimes(1); + expect(sendMailMock).toHaveBeenCalledTimes(1); +}); + +test("Can create email strings (vague)", () => { + expect(reset.createEmail("myresetcode")).toBeTruthy(); +}); + +test("Can request reset", async () => { + const req = getMockReq(); + + await expect(reset.requestReset(req)).resolves.toStrictEqual({}); + expectSentMail(); + expectSetupGapi(); + expectCall(reqMock.parseRequestResetRequest, req); + expectCall(ormPMock.getPasswordPersonByEmail, "jeffrey@jan.com"); +}); + +test("Can't request reset for invalid person (v1)", async () => { + ormPMock.getPasswordPersonByEmail.mockResolvedValue(null); + const req = getMockReq(); + + await expect(reset.requestReset(req)).rejects.toStrictEqual( + config.apiErrors.reset.invalidEmail + ); + expect(createTranspMock).not.toHaveBeenCalled(); + expect(sendMailMock).not.toHaveBeenCalled(); + expect(closeTranspMock).not.toHaveBeenCalled(); + expect(createAuthClientMock).not.toHaveBeenCalled(); + expect(createAuthClientMock).not.toHaveBeenCalled(); + expect(setCredMock).not.toHaveBeenCalled(); + expect(gapiMock.Auth.OAuth2Client).not.toHaveBeenCalled(); + expectCall(reqMock.parseRequestResetRequest, req); + expectCall(ormPMock.getPasswordPersonByEmail, "jeffrey@jan.com"); +}); + +test("Can't request reset for invalid person (v2)", async () => { + ormPMock.getPasswordPersonByEmail.mockResolvedValue({ login_user: null }); + const req = getMockReq(); + + await expect(reset.requestReset(req)).rejects.toStrictEqual( + config.apiErrors.reset.invalidEmail + ); + expect(createTranspMock).not.toHaveBeenCalled(); + expect(sendMailMock).not.toHaveBeenCalled(); + expect(closeTranspMock).not.toHaveBeenCalled(); + expect(createAuthClientMock).not.toHaveBeenCalled(); + expect(createAuthClientMock).not.toHaveBeenCalled(); + expect(setCredMock).not.toHaveBeenCalled(); + expect(gapiMock.Auth.OAuth2Client).not.toHaveBeenCalled(); + expectCall(reqMock.parseRequestResetRequest, req); + expectCall(ormPMock.getPasswordPersonByEmail, "jeffrey@jan.com"); +}); + +test("Can check code", async () => { + const req = getMockReq(); + req.body = { code: "valid_code_believe_me_okay?" }; + + await expect(reset.checkCode(req)).resolves.toStrictEqual({}); + expectCall(reqMock.parseCheckResetCodeRequest, req); + expectCall(ormPRMock.findResetByCode, req.body.code); +}); + +test("Code is invalid if code doesn't exist", async () => { + const req = getMockReq(); + req.body = { code: "some_invalid_code???" }; + + await expect(reset.checkCode(req)).rejects.toStrictEqual( + config.apiErrors.reset.resetFailed + ); + expectCall(reqMock.parseCheckResetCodeRequest, req); + expectCall(ormPRMock.findResetByCode, req.body.code); +}); + +test("Code is invalid if code is outdated", async () => { + const req = getMockReq(); + req.body = { code: "outdate_code" }; + + await expect(reset.checkCode(req)).rejects.toStrictEqual( + config.apiErrors.reset.resetFailed + ); + expectCall(reqMock.parseCheckResetCodeRequest, req); + expectCall(ormPRMock.findResetByCode, req.body.code); +}); + +test("Can reset password", async () => { + const req = getMockReq(); + const old = req.headers; + req.body = { code: "valid_code_believe_me_okay?", password: "new_pass" }; + + await expect(reset.resetPassword(req)).resolves.toStrictEqual({ + sessionkey: "key", + }); + expect(req.headers.authorization).toBe(config.global.authScheme + " key"); + req.headers = old; + expectCall(reqMock.parseResetPasswordRequest, req); + expectCall(ormPRMock.findResetByCode, req.body.code); + expect(bcryptMock.hash).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.getLoginUserById, 0); + expectCall(ormLUMock.updateLoginUser, { + loginUserId: 0, + isAdmin: false, + isCoach: true, + accountStatus: "ACTIVATED", + password: "new_pass", + }); + expect(ormSK.addSessionKey).toHaveBeenCalledTimes(1); + expectCall(ormPRMock.deleteResetWithResetId, req.body.code); +}); + +test("Can't reset password (invalid code)", async () => { + const req = getMockReq(); + req.body = { code: "some_invalid_code???", password: "new_pass" }; + + await expect(reset.resetPassword(req)).rejects.toStrictEqual(undefined); + expectCall(reqMock.parseResetPasswordRequest, req); + expectCall(ormPRMock.findResetByCode, req.body.code); + expect(bcryptMock.hash).not.toHaveBeenCalled(); + expect(ormLUMock.getLoginUserById).not.toHaveBeenCalled(); + expect(ormLUMock.updateLoginUser).not.toHaveBeenCalled(); + expect(ormSK.addSessionKey).not.toHaveBeenCalled(); + expect(ormPRMock.deleteResetWithResetId).not.toHaveBeenCalled(); +}); + +test("Can't reset password (outdated code)", async () => { + const req = getMockReq(); + req.body = { code: "outdate_code", password: "new_pass" }; + + await expect(reset.resetPassword(req)).rejects.toStrictEqual(undefined); + expectCall(reqMock.parseResetPasswordRequest, req); + expectCall(ormPRMock.findResetByCode, req.body.code); + expect(bcryptMock.hash).not.toHaveBeenCalled(); + expect(ormLUMock.getLoginUserById).not.toHaveBeenCalled(); + expect(ormLUMock.updateLoginUser).not.toHaveBeenCalled(); + expect(ormSK.addSessionKey).not.toHaveBeenCalled(); + expect(ormPRMock.deleteResetWithResetId).not.toHaveBeenCalled(); +}); + +test("Can reset password", async () => { + ormPRMock.deleteResetWithResetId.mockRejectedValue({}); + const req = getMockReq(); + req.body = { code: "valid_code_believe_me_okay?", password: "new_pass" }; + + await expect(reset.resetPassword(req)).rejects.toStrictEqual( + config.apiErrors.reset.resetFailed + ); + expectCall(reqMock.parseResetPasswordRequest, req); + expectCall(ormPRMock.findResetByCode, req.body.code); + expect(bcryptMock.hash).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.getLoginUserById, 0); + expectCall(ormLUMock.updateLoginUser, { + loginUserId: 0, + isAdmin: false, + isCoach: true, + accountStatus: "ACTIVATED", + password: "new_pass", + }); + expect(ormSK.addSessionKey).toHaveBeenCalledTimes(1); + expectCall(ormPRMock.deleteResetWithResetId, req.body.code); +}); diff --git a/backend/tests/routes_unit/role.test.ts b/backend/tests/routes_unit/role.test.ts new file mode 100644 index 00000000..4a9ecb5c --- /dev/null +++ b/backend/tests/routes_unit/role.test.ts @@ -0,0 +1,136 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { WithUserID } from "../../types"; + +// setup mock for request +import * as req from "../../request"; +jest.mock("../../request"); +const reqMock = req as jest.Mocked; + +// setup mock for utility +import * as util from "../../utility"; +jest.mock("../../utility", () => { + const og = jest.requireActual("../../utility"); + return { + ...og, + checkSessionKey: jest.fn(), + isAdmin: jest.fn(), + }; // we want to only mock checkSessionKey and isAdmin +}); +const utilMock = util as jest.Mocked; + +// setup mocks for orm +import * as ormo from "../../orm_functions/role"; +jest.mock("../../orm_functions/role"); +const ormoMock = ormo as jest.Mocked; + +import * as role from "../../routes/role"; + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +type KD = { abcd: WithUserID; defg: WithUserID }; +function keyData(v: T): KD { + return { + abcd: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }, + defg: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }, + }; +} + +const roles = [ + { role_id: 1, name: "Data scientist" }, + { role_id: 49, name: "Software Dev" }, + { role_id: 4, name: "Frontend Dev" }, +]; + +beforeEach(() => { + reqMock.parseStudentRoleRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseRolesAllRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }) + ); + utilMock.isAdmin.mockImplementation((v) => + v.sessionkey == "abcd" + ? Promise.resolve(keyData(v).abcd) + : Promise.reject(util.errors.cookInsufficientRights()) + ); + + ormoMock.createRole.mockImplementation((y) => + Promise.resolve({ role_id: 0, name: y }) + ); + ormoMock.getAllRoles.mockResolvedValue(roles); +}); + +afterEach(() => { + reqMock.parseStudentRoleRequest.mockReset(); + reqMock.parseRolesAllRequest.mockReset(); + + utilMock.checkSessionKey.mockReset(); + utilMock.isAdmin.mockReset(); + + ormoMock.createRole.mockReset(); + ormoMock.getAllRoles.mockReset(); +}); + +test("Can create a new role", async () => { + const r = getMockReq(); + r.body = { sessionkey: "abcd", name: "New role" }; + ormoMock.getRolesByName.mockResolvedValue(null); + await expect(role.createStudentRole(r)).resolves.toStrictEqual({ + name: "New role", + id: 0, + }); + expectCall(reqMock.parseStudentRoleRequest, r); + expectCall(ormoMock.createRole, "New role"); + expectCall(utilMock.checkSessionKey, { + name: "New role", + sessionkey: "abcd", + }); + + ormoMock.getRolesByName.mockReset(); +}); + +test("Can get all the roles", async () => { + const r = getMockReq(); + r.body = { sessionkey: "abcd" }; + await expect(role.listStudentRoles(r)).resolves.toStrictEqual({ + data: roles, + }); + expectCall(reqMock.parseRolesAllRequest, r); + expect(ormoMock.getAllRoles).toHaveBeenCalledTimes(1); + expectCall(utilMock.checkSessionKey, { + sessionkey: "abcd", + }); +}); diff --git a/backend/tests/routes_unit/student.test.ts b/backend/tests/routes_unit/student.test.ts new file mode 100644 index 00000000..b48bedc2 --- /dev/null +++ b/backend/tests/routes_unit/student.test.ts @@ -0,0 +1,2630 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { Decision, WithUserID } from "../../types"; +import { + email_status_enum, + type_enum, + decision_enum, + account_status_enum, +} from "@prisma/client"; +import { errors } from "../../utility"; + +// setup mock for request +import * as req from "../../request"; +jest.mock("../../request"); +const reqMock = req as jest.Mocked; + +// setup mock for utility +import * as util from "../../utility"; +jest.mock("../../utility", () => { + const og = jest.requireActual("../../utility"); + return { + ...og, + checkSessionKey: jest.fn(), + isAdmin: jest.fn(), + checkYearPermissionStudent: jest.fn(), + }; // we want to only mock checkSessionKey and isAdmin +}); +const utilMock = util as jest.Mocked; + +// setup mocks for orm +import * as ormo from "../../orm_functions/student"; +jest.mock("../../orm_functions/student"); +const ormoMock = ormo as jest.Mocked; + +import * as ormoPerson from "../../orm_functions/person"; +jest.mock("../../orm_functions/person"); +const ormoMockPerson = ormoPerson as jest.Mocked; + +import * as ormoLogin from "../../orm_functions/login_user"; +jest.mock("../../orm_functions/login_user"); +const ormoMockLogin = ormoLogin as jest.Mocked; + +import * as ormoJob from "../../orm_functions/job_application"; +jest.mock("../../orm_functions/job_application"); +const ormoMockJob = ormoJob as jest.Mocked; + +import * as ormoRole from "../../orm_functions/role"; +jest.mock("../../orm_functions/role"); +const ormoMockRole = ormoRole as jest.Mocked; + +import * as ormoSt from "../../orm_functions/student"; +jest.mock("../../orm_functions/student"); +const ormoMockStudent = ormoSt as jest.Mocked; + +import * as ormoLanguage from "../../orm_functions/language"; +jest.mock("../../orm_functions/language"); +const ormoMockLanguage = ormoLanguage as jest.Mocked; + +import * as ormoOsoc from "../../orm_functions/osoc"; +jest.mock("../../orm_functions/osoc"); +const ormoMockOsoc = ormoOsoc as jest.Mocked; + +import * as ormoEval from "../../orm_functions/evaluation"; +jest.mock("../../orm_functions/evaluation"); +const ormoMockEval = ormoEval as jest.Mocked; + +import * as student from "../../routes/student"; + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +type KD = { abcd: WithUserID; defg: WithUserID }; +function keyData(v: T): KD { + return { + abcd: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }, + defg: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }, + }; +} + +const filter_student = { + pagination: { + page: 0, + count: 3, + }, + data: [ + { + student_id: 0, + person_id: 0, + gender: "Male", + pronouns: "", + phone_number: "0457441257", + nickname: "Wizard", + alumni: true, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + github_id: "0", + }, + job_application: [ + { + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibiliy0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPLIED, + created_at: new Date("2022-03-14 23:10:00+01"), + evaluation: [ + { + evaluation_id: 0, + motivation: "good eval 0", + decision: decision_enum.YES, + is_final: true, + login_user: { + login_user_id: 0, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + }, + }, + }, + ], + attachment: [ + { + attachment_id: 0, + job_application_id: 0, + data: ["attachment0"], + type: [type_enum.MOTIVATION_STRING], + }, + ], + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "skill0", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + role: { + role_id: 0, + name: "Role0", + }, + }, + ], + language_id: 0, + }, + ], + }, + ], +}; + +const students = [ + { + student_id: 0, + person_id: 0, + gender: "Male", + pronouns: "", + phone_number: "0457441257", + nickname: "Wizard", + alumni: true, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + github_id: "0", + }, + }, + { + student_id: 1, + person_id: 1, + gender: "Female", + pronouns: "", + phone_number: "0489653214", + nickname: "Unicorn", + alumni: true, + person: { + person_id: 1, + name: "person1", + email: "person1@mail.com", + github: "", + github_id: "1", + }, + }, + { + student_id: 2, + person_id: 2, + gender: "Male", + pronouns: "", + phone_number: "0484623584", + nickname: "Legend", + alumni: false, + person: { + person_id: 2, + name: "person2", + email: "person2@mail.com", + github: "", + github_id: "2", + }, + }, +]; + +const latestJobApplication = [ + { + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibiliy0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPLIED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [ + { + attachment_id: 0, + job_application_id: 0, + data: ["attachment0"], + type: [type_enum.MOTIVATION_STRING], + }, + ], + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "skill0", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + }, + ], + language_id: 0, + osoc: { + osoc_id: 0, + year: 2022, + }, + }, + { + job_application_id: 1, + student_id: 1, + responsibilities: "Responsibiliy1", + fun_fact: "Funfact1", + student_volunteer_info: "Volunteer1", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPLIED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [ + { + attachment_id: 1, + job_application_id: 1, + data: ["attachment1"], + type: [type_enum.MOTIVATION_STRING], + }, + ], + job_application_skill: [ + { + job_application_skill_id: 1, + job_application_id: 1, + skill: "skill1", + language_id: 1, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + applied_role: [ + { + role_id: 1, + applied_role_id: 1, + job_application_id: 1, + }, + ], + language_id: 1, + osoc: { + osoc_id: 0, + year: 2022, + }, + }, + { + job_application_id: 2, + student_id: 2, + responsibilities: "Responsibiliy2", + fun_fact: "Funfact2", + student_volunteer_info: "Volunteer2", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPLIED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [ + { + attachment_id: 2, + job_application_id: 2, + data: ["attachment2"], + type: [type_enum.MOTIVATION_STRING], + }, + ], + job_application_skill: [ + { + job_application_skill_id: 2, + job_application_id: 2, + skill: "skill2", + language_id: 2, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + applied_role: [ + { + role_id: 2, + applied_role_id: 2, + job_application_id: 2, + }, + ], + language_id: 2, + osoc: { + osoc_id: 0, + year: 2022, + }, + }, +]; + +const roles = [ + { + role_id: 0, + name: "Role0", + }, + { + role_id: 1, + name: "Role1", + }, + { + role_id: 2, + name: "Role2", + }, +]; + +const studentEvaluations = [ + [ + { + osoc: { osocid: 0, year: 2022 }, + evaluation: [ + { + evaluation_id: 0, + motivation: "good eval 0", + decision: decision_enum.YES, + is_final: true, + login_user: { + login_user_id: 0, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + }, + }, + }, + ], + }, + ], + [ + { + osoc: { osocid: 0, year: 2022 }, + evaluation: [ + { + evaluation_id: 0, + motivation: "good eval 0", + decision: decision_enum.YES, + is_final: true, + login_user: { + login_user_id: 0, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + }, + }, + }, + ], + }, + ], + [ + { + osoc: { osocid: 0, year: 2022 }, + evaluation: [ + { + evaluation_id: 0, + motivation: "good eval 0", + decision: decision_enum.YES, + is_final: true, + login_user: { + login_user_id: 0, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + }, + }, + }, + ], + }, + ], +]; +const studentEvaluationsByYear = [ + { + evaluation: [ + { + evaluation_id: 0, + motivation: "good eval 0", + decision: decision_enum.YES, + is_final: true, + login_user: { + login_user_id: 0, + person_id: 0, + account_status: account_status_enum.ACTIVATED, + is_admin: true, + is_coach: true, + password: "Password", + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + github_id: "0", + }, + }, + }, + ], + }, + + { + evaluation: [ + { + evaluation_id: 0, + motivation: "good eval 0", + decision: decision_enum.YES, + is_final: true, + login_user: { + login_user_id: 0, + person_id: 0, + account_status: account_status_enum.ACTIVATED, + is_admin: true, + is_coach: true, + password: "Password", + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + github_id: "0", + }, + }, + }, + ], + }, + + { + evaluation: [ + { + evaluation_id: 0, + motivation: "good eval 0", + decision: decision_enum.YES, + is_final: true, + login_user: { + login_user_id: 0, + person_id: 0, + account_status: account_status_enum.ACTIVATED, + is_admin: true, + is_coach: true, + password: "Password", + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + github_id: "0", + }, + }, + }, + ], + }, +]; +const language = [ + { + language_id: 0, + name: "language0", + }, + { + language_id: 1, + name: "language1", + }, + { + language_id: 1, + name: "language1", + }, +]; + +beforeEach(() => { + reqMock.parseStudentAllRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseSingleStudentRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseDeleteStudentRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseSuggestStudentRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseGetSuggestionsStudentRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseFinalizeDecisionRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseFilterStudentsRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }) + ); + utilMock.isAdmin.mockImplementation((v) => + v.sessionkey == "abcd" + ? Promise.resolve(keyData(v).abcd) + : Promise.reject(util.errors.cookInsufficientRights()) + ); + + ormoMock.getAllStudents.mockResolvedValue(students); + ormoMock.deleteStudent.mockImplementation((y) => + Promise.resolve(students[y]) + ); + ormoMock.filterStudents.mockImplementation(() => + Promise.resolve(filter_student) + ); + ormoMockPerson.deletePersonById.mockImplementation((y) => + Promise.resolve(students[y].person) + ); + ormoMock.getStudent.mockImplementation((y) => Promise.resolve(students[y])); + ormoMockJob.getLatestJobApplicationOfStudent.mockImplementation((y) => + Promise.resolve(latestJobApplication[y]) + ); + ormoMockJob.getStudentEvaluationsTemp.mockImplementation((y) => + Promise.resolve(studentEvaluations[y]) + ); + ormoMockJob.getEvaluationsByYearForStudent.mockImplementation((id) => + Promise.resolve(studentEvaluationsByYear[id]) + ); + ormoMockRole.getRole.mockImplementation((y) => Promise.resolve(roles[y])); + ormoMockJob.getStudentEvaluationsTotal.mockImplementation((y) => + Promise.resolve(studentEvaluations[y]) + ); + ormoMockLanguage.getLanguage.mockImplementation((y) => + Promise.resolve(language[y]) + ); + ormoMockOsoc.getLatestOsoc.mockImplementation(() => + Promise.resolve({ osoc_id: 0, year: 2022 }) + ); + ormoMockEval.createEvaluationForStudent.mockImplementation(() => + Promise.resolve({ + evaluation_id: 0, + login_user_id: 0, + job_application_id: 0, + decision: Decision.NO, + motivation: "You are not accepted for osoc", + is_final: true, + }) + ); + ormoMockEval.updateEvaluationForStudent.mockImplementation((y) => + Promise.resolve({ + evaluation_id: y.evaluation_id, + login_user_id: y.loginUserId, + job_application_id: 0, + decision: y.decision || decision_enum.YES, + motivation: y.motivation || null, + is_final: false, + }) + ); + + ormoMockLogin.getLoginUserById.mockImplementation((id) => + Promise.resolve(studentEvaluationsByYear[id].evaluation[0].login_user) + ); + + utilMock.checkYearPermissionStudent.mockImplementation((v) => + Promise.resolve(v) + ); +}); + +afterEach(() => { + utilMock.checkYearPermissionStudent.mockReset(); + reqMock.parseStudentAllRequest.mockReset(); + reqMock.parseSingleStudentRequest.mockReset(); + reqMock.parseDeleteStudentRequest.mockReset(); + reqMock.parseSuggestStudentRequest.mockReset(); + reqMock.parseGetSuggestionsStudentRequest.mockReset(); + reqMock.parseFinalizeDecisionRequest.mockReset(); + reqMock.parseFilterStudentsRequest.mockReset(); + + utilMock.checkSessionKey.mockReset(); + utilMock.isAdmin.mockReset(); + + ormoMock.getAllStudents.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMock.filterStudents.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); + ormoMockRole.getRole.mockReset(); + ormoMockJob.getStudentEvaluationsTotal.mockReset(); + ormoMockLanguage.getLanguage.mockReset(); + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMockEval.updateEvaluationForStudent.mockReset(); + ormoMockEval.createEvaluationForStudent.mockReset(); + ormoMockLogin.getLoginUserById.mockReset(); +}); + +test("Fails if no student was found in getStudent", async () => { + const r = getMockReq(); + const id = 1000; + + r.body = { + sessionkey: "abcd", + year: 2025, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce(null); + + await expect(student.getStudent(r)).rejects.toBe(errors.cookInvalidID()); + + ormoMock.getStudent.mockReset(); +}); + +test("Latest osoc year is null in getStudent", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + }; + + r.params.id = id.toString(); + + // override + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue(null); + ormoMockOsoc.getLatestOsoc.mockResolvedValue(null); + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + await expect(student.getStudent(r)).rejects.toBe(errors.cookInvalidID()); + + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMock.getStudent.mockReset(); +}); + +test("Job application wasn't found in getStudent", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + }; + + r.params.id = id.toString(); + + // override + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue(null); + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + await expect(student.getStudent(r)).rejects.toBe(errors.cookInvalidID()); + + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMock.getStudent.mockReset(); +}); + +test("Role wasn't found in getStudent", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockRole.getRole.mockResolvedValue(null); + + await expect(student.getStudent(r)).rejects.toBe(errors.cookInvalidID()); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMockRole.getRole.mockReset(); + ormoMock.getStudent.mockReset(); +}); + +test("Year is defined in the getStudent request and skill language is invalid", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [ + { + is_best: true, + is_preferred: true, + job_application_id: 0, + job_application_skill_id: 0, + language_id: 0, + level: 3, + skill: "language0", + }, + ], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + ormoMockRole.getRole.mockResolvedValue({ + role_id: 0, + name: "Developer", + }); + + ormoMockLanguage.getLanguage.mockResolvedValue(null); + + await expect(student.getStudent(r)).rejects.toBe(errors.cookInvalidID()); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMockRole.getRole.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); + ormoMockLanguage.getLanguage.mockReset(); +}); + +test("Can create a student confirmation", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 0, + reply: Decision.NO, + reason: "You are not accepted for osoc", + job_application_id: 0, + }; + await expect(student.createStudentConfirmation(r)).resolves.toStrictEqual( + {} + ); + expectCall(reqMock.parseFinalizeDecisionRequest, r); + expectCall(utilMock.checkSessionKey, r.body); + expectCall(ormoMock.getStudent, 0); + expectCall(ormoMockEval.createEvaluationForStudent, { + loginUserId: 0, + jobApplicationId: 0, + decision: Decision.NO, + motivation: "You are not accepted for osoc", + isFinal: true, + }); +}); + +test("Can create a student evaluation", async () => { + const r = getMockReq(); + + // override + ormoMockJob.getStudentEvaluationsTemp.mockReset(); + ormoMockJob.getStudentEvaluationsTemp.mockResolvedValue([]); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibility0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPROVED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [], + job_application_skill: [], + applied_role: [], + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + r.body = { + sessionkey: "abcd", + id: 0, + suggestion: "YES", + reason: "You are not accepted for osoc", + job_application_id: 0, + }; + await expect(student.createStudentSuggestion(r)).resolves.toStrictEqual({}); + expectCall(reqMock.parseSuggestStudentRequest, r); + expectCall(utilMock.checkSessionKey, r.body); + expectCall(ormoMock.getStudent, 0); + expectCall(ormoMockEval.createEvaluationForStudent, { + loginUserId: 0, + jobApplicationId: 0, + decision: "YES", + motivation: "You are not accepted for osoc", + isFinal: false, + }); + + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); +}); + +test("Different job application id's in createStudentSuggestion", async () => { + const r = getMockReq(); + + r.body = { + sessionkey: "abcd", + id: 0, + suggestion: "YES", + reason: "You are not accepted for osoc", + job_application_id: 1, + }; + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockOsoc.getLatestOsoc.mockResolvedValue({ + osoc_id: 0, + year: 2022, + }); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibility0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPROVED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [], + job_application_skill: [], + applied_role: [], + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(student.createStudentSuggestion(r)).rejects.toBe( + errors.cookWrongSuggestionYear() + ); + + ormoMock.getStudent.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMockOsoc.getLatestOsoc.mockReset(); +}); + +test("Fails if no student was found in createStudentSuggestion", async () => { + const r = getMockReq(); + const id = 1000; + + r.body = { + sessionkey: "abcd", + suggestion: "YES", + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce(null); + + await expect(student.createStudentSuggestion(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMock.getStudent.mockReset(); +}); + +test("No osoc year in the database for createStudentSuggestion", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + suggestion: "YES", + job_application_id: 0, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibiliy0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPROVED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [ + { + attachment_id: 0, + job_application_id: 0, + data: ["attachment0"], + type: [type_enum.MOTIVATION_STRING], + }, + ], + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "skill0", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + }, + ], + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormoMockOsoc.getLatestOsoc.mockResolvedValue(null); + + await expect(student.createStudentSuggestion(r)).rejects.toBe( + errors.cookNoDataError() + ); + + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMock.getStudent.mockReset(); +}); + +test("Can get student suggestions", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 0, + }; + + const result = { + evaluation: { + evaluations: [ + { + decision: "YES", + evaluation_id: 0, + is_final: true, + login_user: { + account_status: "ACTIVATED", + is_admin: true, + is_coach: true, + login_user_id: 0, + password: "Password", + person: { + email: "person0@mail.com", + github: "", + github_id: "0", + name: "person0", + person_id: 0, + }, + person_id: 0, + }, + motivation: "good eval 0", + }, + ], + osoc: { + year: 2022, + }, + }, + }; // please clean up? + await expect(student.getStudentSuggestions(r)).resolves.toStrictEqual( + result + ); + expectCall(reqMock.parseGetSuggestionsStudentRequest, r); + expectCall(utilMock.checkSessionKey, r.body); + expectCall(ormoMock.getStudent, 0); +}); + +test("Can delete a student by id", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 0, + }; + ormoMockStudent.deleteStudentFromDB.mockResolvedValue(); + await expect(student.deleteStudent(r)).resolves.toStrictEqual({}); + expectCall(reqMock.parseDeleteStudentRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.deleteStudentFromDB, 0); + ormoMockStudent.deleteStudentFromDB.mockReset(); +}); + +test("Job application is null for filterStudents", async () => { + const r = getMockReq(); + + r.body = { + sessionkey: "abcd", + osocYear: 2022, + }; + + // override + ormoMock.filterStudents.mockResolvedValueOnce(filter_student); + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue(null); + + await expect(student.filterStudents(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMock.filterStudents.mockReset(); +}); + +test("Role wasn't found in filterStudents", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + }; + + r.params.id = id.toString(); + + // override + ormoMock.filterStudents.mockResolvedValueOnce(filter_student); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibiliy0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPLIED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [ + { + attachment_id: 0, + job_application_id: 0, + data: ["attachment0"], + type: [type_enum.MOTIVATION_STRING], + }, + ], + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "skill0", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + }, + ], + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormoMockRole.getRole.mockResolvedValue(null); + + await expect(student.filterStudents(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMockRole.getRole.mockReset(); + ormoMock.filterStudents.mockReset(); +}); + +test("Skill language is invalid for filterStudents", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + r.params.id = id.toString(); + + // override + ormoMock.filterStudents.mockResolvedValueOnce(filter_student); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibiliy0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPLIED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [ + { + attachment_id: 0, + job_application_id: 0, + data: ["attachment0"], + type: [type_enum.MOTIVATION_STRING], + }, + ], + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "skill0", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + }, + ], + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + ormoMockLanguage.getLanguage.mockResolvedValue(null); + + await expect(student.filterStudents(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMock.filterStudents.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); + ormoMockLanguage.getLanguage.mockReset(); +}); + +test("Suggestion not empty in createStudentSuggestion", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + suggestion: "YES", + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418386", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + ormoMockOsoc.getLatestOsoc.mockResolvedValue({ + year: 2022, + osoc_id: 1, + }); + + ormoMockJob.getStudentEvaluationsTemp.mockResolvedValue([ + { + osoc: { year: 2022 }, + evaluation: [ + { + decision: Decision.YES, + motivation: null, + evaluation_id: 1, + is_final: false, + login_user: { + login_user_id: 1, + person: { + person_id: 2, + name: "Login user", + email: "user@mail.com", + github: null, + }, + }, + }, + ], + }, + ]); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue(null); + + await expect(student.createStudentSuggestion(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMockJob.getStudentEvaluationsTemp.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); +}); + +test("Update evaluation in createStudentSuggestion", async () => { + const r = getMockReq(); + const id = 1; + + r.body = { + sessionkey: "abcd", + suggestion: "YES", + job_application_id: 0, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Female", + pronouns: null, + phone_number: "0923418387", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + ormoMockOsoc.getLatestOsoc.mockResolvedValue({ + year: 2022, + osoc_id: 1, + }); + + ormoMockJob.getStudentEvaluationsTemp.mockResolvedValue([ + { + osoc: { year: 2022 }, + evaluation: [ + { + decision: Decision.YES, + motivation: null, + evaluation_id: 1, + is_final: false, + login_user: { + login_user_id: 1, + person: { + person_id: 2, + name: "Login user", + email: "usermail@mail.com", + github: null, + }, + }, + }, + ], + }, + ]); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 4, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "4", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 1, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }) + ); + + await expect(student.createStudentSuggestion(r)).resolves.toStrictEqual({}); + + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMockJob.getStudentEvaluationsTemp.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + utilMock.checkSessionKey.mockReset(); +}); + +test("New evaluation in createStudentSuggestion", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + suggestion: "YES", + job_application_id: 0, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418387", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + ormoMockOsoc.getLatestOsoc.mockResolvedValue({ + year: 2022, + osoc_id: 1, + }); + + ormoMockJob.getStudentEvaluationsTemp.mockResolvedValue([]); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + applied_role: [ + { + applied_role_id: 0, + job_application_id: 0, + role_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 1, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + ormoMockEval.createEvaluationForStudent.mockResolvedValue({ + login_user_id: null, + evaluation_id: 3, + job_application_id: 0, + decision: Decision.NO, + motivation: null, + is_final: false, + }); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }) + ); + + await expect(student.createStudentSuggestion(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMockJob.getStudentEvaluationsTemp.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + utilMock.checkSessionKey.mockReset(); + ormoMockEval.createEvaluationForStudent.mockReset(); +}); + +test("Fails if no student was found in getStudentSuggestions", async () => { + const r = getMockReq(); + const id = 1000; + + r.body = { + sessionkey: "abcd", + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce(null); + + await expect(student.getStudentSuggestions(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMock.getStudent.mockReset(); +}); + +test("Student was found in getStudentSuggestions", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + year: 2023, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 2, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + await expect(student.getStudentSuggestions(r)).resolves.toStrictEqual({ + evaluation: { + evaluations: [], + osoc: { + year: 2023, + }, + }, + }); + + ormoMock.getStudent.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); +}); + +test("Student was found in getStudentSuggestions and latest osoc is null", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 2, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockOsoc.getLatestOsoc.mockResolvedValue(null); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + await expect(student.getStudentSuggestions(r)).resolves.toStrictEqual({ + evaluation: { + evaluations: [], + osoc: { + year: 2022, + }, + }, + }); + + ormoMock.getStudent.mockReset(); + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); +}); + +test("Fails if no student was found in createStudentConfirmation", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + reply: Decision.YES, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce(null); + + utilMock.isAdmin.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }) + ); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }) + ); + + await expect(student.createStudentConfirmation(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMock.getStudent.mockReset(); + utilMock.isAdmin.mockReset(); + utilMock.checkSessionKey.mockReset(); +}); + +test("Job application is null in getStudentSuggestions", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + reply: Decision.YES, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 2, + person_id: 3, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 3, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + utilMock.isAdmin.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }) + ); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue(null); + + await expect(student.createStudentConfirmation(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMock.getStudent.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + utilMock.isAdmin.mockReset(); +}); + +test("No admin in createStudentConfirmation", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + reply: Decision.YES, + }; + + r.params.id = id.toString(); + + utilMock.isAdmin.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }) + ); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }) + ); + + await expect(student.createStudentConfirmation(r)).rejects.toBe( + errors.cookInsufficientRights() + ); + + utilMock.isAdmin.mockReset(); + utilMock.checkSessionKey.mockReset(); +}); + +test("Evaluations null in getStudent", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + await expect(student.getStudent(r)).resolves.toStrictEqual({ + student: { + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }, + jobApplication: { + applied_role: [], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }, + evaluation: { + osoc: { + year: 2022, + }, + evaluations: [], + }, + evaluations: undefined, + roles: [], + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); +}); + +test("Evaluations null in filterStudents", async () => { + const r = getMockReq(); + + r.body = { + sessionkey: "abcd", + osocYear: 2022, + }; + + // override + ormoMock.filterStudents.mockResolvedValueOnce({ + pagination: { + page: 0, + count: 3, + }, + data: [ + { + student_id: 0, + person_id: 0, + gender: "Male", + pronouns: "", + phone_number: "0457441257", + nickname: "Wizard", + alumni: true, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + github_id: "0", + }, + job_application: [ + { + evaluation: [], + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + role: { + name: "Role0", + }, + }, + ], + student_coach: true, + }, + ], + }, + ], + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 2, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "2", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + ormoMockRole.getRole.mockResolvedValue({ + name: "Role0", + role_id: 0, + }); + + await expect(student.filterStudents(r)).resolves.toStrictEqual({ + pagination: { + page: 0, + count: 3, + }, + data: [ + { + student: { + student_id: 0, + person_id: 0, + gender: "Male", + pronouns: "", + phone_number: "0457441257", + job_application: [ + { + evaluation: [], + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + role: { + name: "Role0", + }, + }, + ], + student_coach: true, + }, + ], + nickname: "Wizard", + alumni: true, + person: { + person_id: 0, + name: "person0", + email: "person0@mail.com", + github: "", + github_id: "0", + }, + }, + jobApplication: { + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 2, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "2", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }, + evaluation: { + osoc: { + year: 2022, + }, + evaluations: [], + }, + evaluations: undefined, + roles: ["Role0"], + }, + ], + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMockRole.getRole.mockReset(); + ormoMock.filterStudents.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); +}); + +test("Evaluations null in getStudent", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "skill0", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + ormoMockLanguage.getLanguage.mockResolvedValue({ + language_id: 0, + name: "English", + }); + + await expect(student.getStudent(r)).resolves.toStrictEqual({ + student: { + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }, + jobApplication: { + applied_role: [], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "English", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + ], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }, + evaluation: { + osoc: { + year: 2022, + }, + evaluations: [], + }, + evaluations: undefined, + roles: [], + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); + ormoMockLanguage.getLanguage.mockReset(); +}); + +test("Different job application id's in createStudentConfirmation", async () => { + const r = getMockReq(); + + r.body = { + sessionkey: "abcd", + id: 0, + suggestion: "YES", + reason: "You are not accepted for osoc", + job_application_id: 1, + }; + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue({ + job_application_id: 0, + student_id: 0, + responsibilities: "Responsibility0", + fun_fact: "Funfact0", + student_volunteer_info: "Volunteer0", + student_coach: true, + osoc_id: 0, + edus: ["Edu0"], + edu_level: "Master", + edu_duration: 5, + edu_year: "5", + edu_institute: "UGent", + email_status: email_status_enum.APPROVED, + created_at: new Date("2022-03-14 23:10:00+01"), + attachment: [], + job_application_skill: [], + applied_role: [], + osoc: { + osoc_id: 0, + year: 2022, + }, + }); + + await expect(student.createStudentConfirmation(r)).rejects.toBe( + errors.cookWrongSuggestionYear() + ); + + ormoMock.getStudent.mockReset(); + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); +}); + +test("Job application is null for filterStudents and latest osoc is null", async () => { + const r = getMockReq(); + + r.body = { + sessionkey: "abcd", + }; + + // override + ormoMock.filterStudents.mockResolvedValueOnce(filter_student); + ormoMockOsoc.getLatestOsoc.mockResolvedValue(null); + ormoMockJob.getLatestJobApplicationOfStudent.mockResolvedValue(null); + + await expect(student.filterStudents(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockJob.getLatestJobApplicationOfStudent.mockReset(); + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMock.filterStudents.mockReset(); +}); + +test("Job application is null for filterStudents", async () => { + const r = getMockReq(); + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + // override + ormoMock.filterStudents.mockResolvedValueOnce(filter_student); + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [ + { + role_id: 0, + applied_role_id: 0, + job_application_id: 0, + }, + ], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 2, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "2", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockRole.getRole.mockResolvedValue(null); + + await expect(student.filterStudents(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMock.filterStudents.mockReset(); + ormoMockRole.getRole.mockReset(); +}); + +test("Skills fail for filterStudents", async () => { + const r = getMockReq(); + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + // override + ormoMock.filterStudents.mockResolvedValueOnce(filter_student); + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 2, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "2", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [ + { + job_application_skill_id: 0, + job_application_id: 0, + skill: "skill0", + language_id: 0, + level: 3, + is_preferred: true, + is_best: true, + }, + { + job_application_skill_id: 1, + job_application_id: 0, + skill: "skill1", + language_id: 1, + level: null, + is_preferred: true, + is_best: true, + }, + ], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue(null); + + ormoMockLanguage.getLanguage.mockResolvedValueOnce({ + language_id: 0, + name: "English", + }); + + ormoMockLanguage.getLanguage.mockResolvedValueOnce(null); + + await expect(student.filterStudents(r)).rejects.toBe( + errors.cookInvalidID() + ); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMockOsoc.getLatestOsoc.mockReset(); + ormoMock.filterStudents.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); + ormoMockLanguage.getLanguage.mockReset(); +}); + +test("Evaluations not null in getStudent", async () => { + const r = getMockReq(); + const id = 0; + + r.body = { + sessionkey: "abcd", + year: 2022, + }; + + r.params.id = id.toString(); + + // override + ormoMock.getStudent.mockResolvedValueOnce({ + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockResolvedValue({ + applied_role: [], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }); + + ormoMockJob.getEvaluationsByYearForStudent.mockResolvedValue({ + evaluation: [ + { + decision: decision_enum.YES, + is_final: false, + motivation: null, + evaluation_id: 0, + login_user: null, + }, + ], + }); + + await expect(student.getStudent(r)).resolves.toStrictEqual({ + student: { + student_id: 1, + person_id: 1, + gender: "Male", + pronouns: null, + phone_number: "0923418389", + nickname: null, + alumni: true, + person: { + person_id: 1, + email: "test@mail.com", + github: null, + name: "Name", + github_id: null, + }, + }, + jobApplication: { + applied_role: [], + attachment: [], + created_at: new Date("2022-03-14T22:10:00.000Z"), + edu_duration: 5, + edu_institute: "UGent", + edu_level: "Master", + edu_year: "5", + edus: ["Edu0"], + email_status: "APPLIED", + fun_fact: "Funfact0", + job_application_id: 0, + job_application_skill: [], + osoc_id: 0, + responsibilities: "Responsibiliy0", + student_coach: true, + student_id: 0, + student_volunteer_info: "Volunteer0", + }, + evaluation: { + osoc: { + year: 2022, + }, + evaluations: [ + { + decision: decision_enum.YES, + is_final: false, + motivation: null, + evaluation_id: 0, + login_user: null, + }, + ], + }, + evaluations: undefined, + roles: [], + }); + + ormoMockJob.getJobApplicationByYearForStudent.mockReset(); + ormoMock.getStudent.mockReset(); + ormoMockJob.getEvaluationsByYearForStudent.mockReset(); +}); diff --git a/backend/tests/routes_unit/template.test.ts b/backend/tests/routes_unit/template.test.ts new file mode 100644 index 00000000..1b0b1fba --- /dev/null +++ b/backend/tests/routes_unit/template.test.ts @@ -0,0 +1,337 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { WithUserID } from "../../types"; +import { CreateTemplate, UpdateTemplate } from "../../orm_functions/orm_types"; + +// setup mock for request +import * as req from "../../request"; +jest.mock("../../request"); +const reqMock = req as jest.Mocked; + +// setup mock for utility +import * as util from "../../utility"; +jest.mock("../../utility", () => { + const og = jest.requireActual("../../utility"); + return { + ...og, + checkSessionKey: jest.fn(), + isAdmin: jest.fn(), + }; // we want to only mock checkSessionKey and isAdmin +}); +const utilMock = util as jest.Mocked; + +// setup mocks for orm +import * as ormo from "../../orm_functions/template"; +jest.mock("../../orm_functions/template"); +const ormoMock = ormo as jest.Mocked; + +import * as template from "../../routes/template"; + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +type KD = { abcd: WithUserID; defg: WithUserID }; +function keyData(v: T): KD { + return { + abcd: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }, + defg: { + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }, + }; +} + +const templates = [ + { + template_email_id: 1, + owner_id: 0, + name: "Osoc contract", + content: "Please sign contract", + cc: "me@osoc.com", + subject: "Osoc Contract", + }, + { + template_email_id: 49, + owner_id: 0, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }, + { + template_email_id: 4, + owner_id: 0, + name: "Osoc password reset", + content: "Hello, password reset", + cc: "me@osoc.com", + subject: "Password reset", + }, +]; + +beforeEach(() => { + reqMock.parseNewTemplateRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseTemplateListRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseGetTemplateRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseUpdateTemplateRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseDeleteTemplateRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + userId: 0, + data: v, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: false, + }) + ); + utilMock.isAdmin.mockImplementation((v) => + v.sessionkey == "abcd" + ? Promise.resolve(keyData(v).abcd) + : Promise.reject(util.errors.cookInsufficientRights()) + ); + + ormoMock.createTemplate.mockImplementation((y: CreateTemplate) => + Promise.resolve({ + template_email_id: 0, + owner_id: y.ownerId, + name: y.name || "", + content: y.content || "", + cc: y.cc || "", + subject: y.subject || "", + }) + ); + ormoMock.getAllTemplates.mockResolvedValue(templates); + ormoMock.getTemplateById.mockImplementation((y) => + Promise.resolve({ + template_email_id: y, + owner_id: 0, + name: "Osoc password reset", + content: "Hello, password reset", + cc: "me@osoc.com", + subject: "Password reset", + }) + ); + ormoMock.updateTemplate.mockImplementation((y: UpdateTemplate) => + Promise.resolve({ + template_email_id: y.templateId, + owner_id: 0, + name: y.name || "", + content: y.content || "", + cc: y.cc || "", + subject: y.subject || "", + }) + ); + ormoMock.deleteTemplate.mockImplementation((y) => + Promise.resolve({ + template_email_id: y, + owner_id: 0, + name: "Osoc contract", + content: "Please sign contract", + cc: "me@osoc.com", + subject: "Osoc Contract", + }) + ); +}); + +afterEach(() => { + reqMock.parseNewTemplateRequest.mockReset(); + reqMock.parseTemplateListRequest.mockReset(); + reqMock.parseGetTemplateRequest.mockReset(); + reqMock.parseUpdateTemplateRequest.mockReset(); + reqMock.parseDeleteTemplateRequest.mockReset(); + + utilMock.checkSessionKey.mockReset(); + utilMock.isAdmin.mockReset(); + + ormoMock.createTemplate.mockReset(); + ormoMock.getAllTemplates.mockReset(); + ormoMock.getTemplateById.mockReset(); + ormoMock.updateTemplate.mockReset(); + ormoMock.deleteTemplate.mockReset(); +}); + +test("Can create a template", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + owner_id: 0, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }; + await expect(template.createTemplate(r)).resolves.toStrictEqual({ + id: 0, + owner: 0, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }); + expectCall(reqMock.parseNewTemplateRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.createTemplate, { + ownerId: 0, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }); +}); + +test("Can get all the templates", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + }; + await expect(template.getAllTemplates(r)).resolves.toStrictEqual({ + data: templates.map((obj) => ({ + id: obj.template_email_id, + owner: obj.owner_id, + name: obj.name, + })), + }); + expectCall(reqMock.parseTemplateListRequest, r); + expectCall(utilMock.isAdmin, r.body); + expect(ormoMock.getAllTemplates).toHaveBeenCalledTimes(1); +}); + +test("Can get a template by id", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 4, + }; + await expect(template.getSingleTemplate(r)).resolves.toStrictEqual({ + id: 4, + owner: 0, + name: "Osoc password reset", + content: "Hello, password reset", + }); + expectCall(reqMock.parseGetTemplateRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.getTemplateById, 4); +}); + +test("Can update a template", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 49, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }; + await expect(template.updateTemplate(r)).resolves.toStrictEqual({ + id: 49, + owner: 0, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }); + expectCall(reqMock.parseUpdateTemplateRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.getTemplateById, 49); + expectCall(ormoMock.updateTemplate, { + templateId: 49, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }); +}); + +test("Can update a template (invalid case)", async () => { + ormoMock.getTemplateById.mockImplementation((y) => + Promise.resolve({ + template_email_id: y, + owner_id: 69, + name: "Osoc password reset", + content: "Hello, password reset", + cc: "me@osoc.com", + subject: "Password reset", + }) + ); + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 49, + name: "Osoc denied", + content: "You are not accepted for osoc", + cc: "me@osoc.com", + subject: "Osoc", + }; + await expect(template.updateTemplate(r)).rejects.toStrictEqual( + template.notOwnerError + ); + expectCall(reqMock.parseUpdateTemplateRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.getTemplateById, 49); +}); + +test("Can delete a template by id", async () => { + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 1, + }; + await expect(template.deleteTemplate(r)).resolves.toStrictEqual({}); + expectCall(reqMock.parseDeleteTemplateRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.getTemplateById, 1); + expectCall(ormoMock.deleteTemplate, 1); +}); + +test("Can delete a template by id (invalid case)", async () => { + ormoMock.getTemplateById.mockImplementation((y) => + Promise.resolve({ + template_email_id: y, + owner_id: 69, + name: "Osoc password reset", + content: "Hello, password reset", + cc: "me@osoc.com", + subject: "Password reset", + }) + ); + const r = getMockReq(); + r.body = { + sessionkey: "abcd", + id: 1, + }; + await expect(template.deleteTemplate(r)).rejects.toStrictEqual( + template.notOwnerError + ); + expectCall(reqMock.parseDeleteTemplateRequest, r); + expectCall(utilMock.isAdmin, r.body); + expectCall(ormoMock.getTemplateById, 1); +}); diff --git a/backend/tests/routes_unit/user.test.ts b/backend/tests/routes_unit/user.test.ts new file mode 100644 index 00000000..9a4a04eb --- /dev/null +++ b/backend/tests/routes_unit/user.test.ts @@ -0,0 +1,709 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { login_user, person } from "@prisma/client"; + +// setup mock for request +import * as req from "../../request"; +jest.mock("../../request"); +const reqMock = req as jest.Mocked; + +// setup mock for utility +import * as util from "../../utility"; +jest.mock("../../utility"); +const utilMock = util as jest.Mocked; + +// setup mock for libs +import * as val from "validator"; +jest.mock("validator"); +const valMock = val.default as jest.Mocked; +import * as bcrypt from "bcrypt"; +jest.mock("bcrypt"); +const bcryptMock = bcrypt as jest.Mocked; + +// setup ORM mocks +import * as ormLU from "../../orm_functions/login_user"; +jest.mock("../../orm_functions/login_user"); +const ormLUMock = ormLU as jest.Mocked; +import * as ormLuOs from "../../orm_functions/login_user_osoc"; +jest.mock("../../orm_functions/login_user_osoc"); +const ormLuOsMock = ormLuOs as jest.Mocked; +import * as ormP from "../../orm_functions/person"; +jest.mock("../../orm_functions/person"); +const ormPMock = ormP as jest.Mocked; +import * as ormSK from "../../orm_functions/session_key"; +jest.mock("../../orm_functions/session_key"); +const ormSKMock = ormSK as jest.Mocked; + +import * as user from "../../routes/user"; +import { errors } from "../../utility"; + +const users: (login_user & { person: person })[] = [ + { + login_user_id: 0, + password: "oldpass", + person_id: 0, + is_admin: false, + is_coach: true, + account_status: "ACTIVATED", + person: { + person_id: 0, + email: "person@one.com", + name: "Person 1", + github: null, + github_id: null, + }, + }, + { + login_user_id: 1, + password: "", + person_id: 1, + is_admin: true, + is_coach: false, + account_status: "ACTIVATED", + person: { + person_id: 1, + email: "person@two.com", + name: "Person 2", + github: null, + github_id: null, + }, + }, + { + login_user_id: 2, + password: "", + person_id: 2, + is_admin: true, + is_coach: true, + account_status: "PENDING", + person: { + person_id: 2, + email: null, + name: "Person 2", + github: "@person___2", + github_id: "9874531208745", + }, + }, +]; + +beforeEach(() => { + valMock.normalizeEmail.mockImplementation((v) => v); + bcryptMock.hash.mockImplementation((v) => Promise.resolve(v)); + bcryptMock.compare.mockImplementation((x, y) => Promise.resolve(x === y)); + + reqMock.parseUserAllRequest.mockResolvedValue({ + currentPage: 0, + pageSize: 25, + sessionkey: "key", + }); + reqMock.parseRequestUserRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseAcceptNewUserRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseFilterUsersRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseUserModSelfRequest.mockImplementation((v) => + Promise.resolve(v.body) + ); + reqMock.parseCurrentUserRequest.mockResolvedValue({ sessionkey: "valid" }); + + utilMock.isAdmin.mockImplementation((v) => { + return Promise.resolve({ + data: v, + userId: 7, + accountStatus: "ACTIVATED", + is_admin: true, + is_coach: true, + }); + }); + utilMock.generateKey.mockImplementation(() => "abcdefghijklmnopqrstuvwxyz"); + utilMock.mutable.mockImplementation((v) => Promise.resolve(v)); + utilMock.checkSessionKey.mockImplementation((v) => + Promise.resolve({ + data: v, + userId: 0, + is_coach: true, + is_admin: true, + accountStatus: "ACTIVATED", + }) + ); + utilMock.getOrReject.mockImplementation((v) => + v == undefined || v == null + ? Promise.reject({ reason: "getorreject" }) + : Promise.resolve(v) + ); + + ormLUMock.getAllLoginUsers.mockResolvedValue(users); + ormLUMock.filterLoginUsers.mockResolvedValue({ + data: users, + pagination: { page: 0, count: users.length }, + }); + ormLUMock.searchLoginUserByPerson.mockImplementation((id) => { + const tmp = users.filter((x) => x.person_id == id); + if (tmp.length > 0) return Promise.resolve(tmp[0]); + return Promise.resolve(null); + }); + ormLUMock.createLoginUser.mockImplementation((cr) => { + return Promise.resolve({ + login_user_id: 255, + person_id: cr.personId, + account_status: "PENDING", + password: cr.password === undefined ? null : cr.password, + is_admin: cr.isAdmin, + is_coach: cr.isCoach, + }); + }); + ormLUMock.updateLoginUser.mockResolvedValue(users[0]); + ormLUMock.getLoginUserById.mockResolvedValue(users[0]); + + ormSKMock.addSessionKey.mockImplementation((id, key, dat) => + Promise.resolve({ + session_key_id: 0, + login_user_id: id, + valid_until: dat, + session_key: key, + }) + ); + + ormPMock.searchPersonByLogin.mockImplementation((email) => + Promise.resolve( + users.filter((x) => x.person.email == email).map((x) => x.person) + ) + ); + + ormPMock.updatePerson.mockImplementation((upd) => { + const tmp = users.filter((x) => x.person_id == upd.personId); + if (tmp.length == 0) return Promise.reject(); + return Promise.resolve(tmp[0].person); + }); + + ormPMock.createPerson.mockImplementation((cr) => { + return Promise.resolve({ + person_id: 69, + github: null, + github_id: null, + name: cr.name, + email: cr.email === undefined ? null : cr.email, + }); + }); + + ormSKMock.removeAllKeysForUser.mockResolvedValue({ count: 1 }); +}); + +afterEach(() => { + valMock.normalizeEmail.mockReset(); + bcryptMock.hash.mockReset(); + bcryptMock.compare.mockReset(); + + reqMock.parseUserAllRequest.mockReset(); + reqMock.parseRequestUserRequest.mockReset(); + reqMock.parseAcceptNewUserRequest.mockReset(); + reqMock.parseFilterUsersRequest.mockReset(); + reqMock.parseUserModSelfRequest.mockReset(); + + utilMock.isAdmin.mockReset(); + utilMock.generateKey.mockReset(); + utilMock.mutable.mockReset(); + utilMock.checkSessionKey.mockReset(); + utilMock.getOrReject.mockReset(); + + ormLUMock.getAllLoginUsers.mockReset(); + ormLUMock.filterLoginUsers.mockReset(); + ormLUMock.searchLoginUserByPerson.mockReset(); + ormLUMock.createLoginUser.mockReset(); + ormLUMock.updateLoginUser.mockReset(); + ormLUMock.getLoginUserById.mockReset(); + ormPMock.searchPersonByLogin.mockReset(); + ormPMock.updatePerson.mockReset(); + ormPMock.createPerson.mockReset(); + ormSKMock.addSessionKey.mockReset(); + ormSKMock.removeAllKeysForUser.mockReset(); +}); + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +test("Can request all users", async () => { + const rq = getMockReq(); + rq.body = { sessionkey: "key" }; + + const res = users.map((x) => ({ + person: { + person_id: x.person.person_id, + name: x.person.name, + email: x.person.email === null ? "" : x.person.email, + github: x.person.github === null ? "" : x.person.github, + }, + is_coach: x.is_coach, + is_admin: x.is_admin, + account_status: x.account_status, + login_user_id: x.login_user_id, + })); + + await expect(user.listUsers(rq)).resolves.toStrictEqual({ + data: res, + pagination: { page: 0, count: res.length }, + }); + expectCall(reqMock.parseUserAllRequest, rq); + expectCall(utilMock.isAdmin, { ...rq.body, currentPage: 0, pageSize: 25 }); + expect(ormLUMock.filterLoginUsers).toHaveBeenCalledTimes(1); +}); + +test("Can't create new users (already in system)", async () => { + ormPMock.searchPersonByLogin.mockResolvedValue([users[0].person]); + ormLUMock.searchLoginUserByPerson.mockResolvedValue(users[0]); + + const req = getMockReq(); + req.body = { + name: users[0].person.name, + email: "person1@one.com", + pass: "nevergonnagiveyouupnevergonnaletyoudown", + }; + + await expect(user.createUserRequest(req)).rejects.toStrictEqual({ + http: 400, + reason: "Can't register the same email address twice.", + }); + + expectCall(reqMock.parseRequestUserRequest, req); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(0); + expect(utilMock.isAdmin).toHaveBeenCalledTimes(0); + expectCall(ormPMock.searchPersonByLogin, req.body.email); + expectCall(ormLUMock.searchLoginUserByPerson, users[0].person_id); + expect(ormPMock.updatePerson).toHaveBeenCalledTimes(0); + expect(ormPMock.createPerson).toHaveBeenCalledTimes(0); + expect(bcryptMock.hash).toHaveBeenCalledTimes(0); + expect(ormLUMock.createLoginUser).toHaveBeenCalledTimes(0); + expect(util.generateKey).toHaveBeenCalledTimes(0); + expect(ormSKMock.addSessionKey).toHaveBeenCalledTimes(0); +}); + +test("Can create new users (person already in system)", async () => { + ormPMock.searchPersonByLogin.mockResolvedValue([users[0].person]); + ormLUMock.searchLoginUserByPerson.mockResolvedValue(null); + + const req = getMockReq(); + req.body = { + name: users[0].person.name, + email: "person1@one.com", + pass: "nevergonnagiveyouupnevergonnaletyoudown", + }; + + await expect(user.createUserRequest(req)).resolves.toStrictEqual({ + id: 255, + sessionkey: "abcdefghijklmnopqrstuvwxyz", + }); + + expectCall(reqMock.parseRequestUserRequest, req); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(0); + expect(utilMock.isAdmin).toHaveBeenCalledTimes(0); + expectCall(ormPMock.searchPersonByLogin, req.body.email); + expectCall(ormLUMock.searchLoginUserByPerson, users[0].person_id); + expectCall(ormPMock.updatePerson, { + personId: users[0].person_id, + name: users[0].person.name, + }); + expect(ormPMock.createPerson).toHaveBeenCalledTimes(0); + expect(bcryptMock.hash).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.createLoginUser, { + personId: users[0].person.person_id, + password: req.body.pass, + isAdmin: false, + isCoach: true, + accountStatus: "PENDING", + }); + expect(util.generateKey).toHaveBeenCalledTimes(1); + expect(ormSKMock.addSessionKey).toHaveBeenCalledTimes(1); +}); + +test("Can create new users (unknown person)", async () => { + ormPMock.searchPersonByLogin.mockResolvedValue([]); + ormLUMock.searchLoginUserByPerson.mockResolvedValue(null); + + const req = getMockReq(); + req.body = { + name: users[0].person.name, + email: "person1@one.com", + pass: "nevergonnagiveyouupnevergonnaletyoudown", + }; + + await expect(user.createUserRequest(req)).resolves.toStrictEqual({ + id: 255, + sessionkey: "abcdefghijklmnopqrstuvwxyz", + }); + + expectCall(reqMock.parseRequestUserRequest, req); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(0); + expect(utilMock.isAdmin).toHaveBeenCalledTimes(0); + expectCall(ormPMock.searchPersonByLogin, req.body.email); + expect(ormLUMock.searchLoginUserByPerson).toHaveBeenCalledTimes(0); + expectCall(ormPMock.createPerson, { + email: req.body.email, + name: users[0].person.name, + }); + expect(ormPMock.updatePerson).toHaveBeenCalledTimes(0); + expect(bcryptMock.hash).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.createLoginUser, { + personId: 69, + password: req.body.pass, + isAdmin: false, + isCoach: true, + accountStatus: "PENDING", + }); + expect(util.generateKey).toHaveBeenCalledTimes(1); + expect(ormSKMock.addSessionKey).toHaveBeenCalledTimes(1); +}); + +test("Can set account status", async () => { + ormLUMock.searchLoginUserByPerson.mockResolvedValue(users[0]); + + await expect( + user.setAccountStatus(0, "PENDING", false, true) + ).resolves.toStrictEqual({ + id: users[0].person_id, + name: users[0].person.name, + }); + expectCall(ormLUMock.searchLoginUserByPerson, 0); + expectCall(ormLUMock.updateLoginUser, { + loginUserId: users[0].login_user_id, + isAdmin: false, + isCoach: true, + accountStatus: "PENDING", + }); +}); + +test("Can accept new users", async () => { + ormLUMock.searchLoginUserByPerson.mockReset(); + ormLUMock.searchLoginUserByPerson.mockResolvedValue(users[2]); + + const req = getMockReq(); + req.body = { sessionkey: "key", id: 1, is_admin: false, is_coach: false }; + + await expect(user.createUserAcceptance(req)).resolves.toStrictEqual({ + id: 0, + name: "Person 1", + }); + expectCall(reqMock.parseAcceptNewUserRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.mutable).toHaveBeenCalledTimes(1); + expect(ormLU.searchLoginUserByPerson).toHaveBeenCalledTimes(2); +}); + +test("Can reject new users", async () => { + ormLUMock.searchLoginUserByPerson.mockReset(); + ormLUMock.searchLoginUserByPerson.mockResolvedValue(users[2]); + + const req = getMockReq(); + req.body = { sessionkey: "key", id: 1, is_admin: false, is_coach: false }; + + await expect(user.deleteUserRequest(req)).resolves.toStrictEqual({ + id: 0, + name: "Person 1", + }); + expectCall(reqMock.parseAcceptNewUserRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.mutable).toHaveBeenCalledTimes(1); + expect(ormLU.searchLoginUserByPerson).toHaveBeenCalledTimes(2); +}); + +test("Can filter users", async () => { + const req = getMockReq(); + req.body = { sessionkey: "key" }; + + const res = users.map((x) => ({ + person: { + person_id: x.person.person_id, + name: x.person.name, + email: x.person.email === null ? "" : x.person.email, + github: x.person.github === null ? "" : x.person.github, + }, + is_coach: x.is_coach, + is_admin: x.is_admin, + account_status: x.account_status, + login_user_id: x.login_user_id, + })); + + await expect(user.filterUsers(req)).resolves.toStrictEqual({ + pagination: { page: 0, count: res.length }, + data: res, + }); + expectCall(reqMock.parseFilterUsersRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(ormLUMock.filterLoginUsers).toHaveBeenCalledTimes(1); +}); + +test("Can modify self", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "abcd", + pass: { oldpass: users[0].password, newpass: "abcde" }, + name: "myname", + }; + + await expect(user.userModSelf(req)).resolves.toStrictEqual({ + sessionkey: "abcdefghijklmnopqrstuvwxyz", + }); + expectCall(reqMock.parseUserModSelfRequest, req); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.getLoginUserById, 0); + expectCall(utilMock.getOrReject, users[0]); + expect(bcryptMock.compare).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.updateLoginUser, { + loginUserId: 0, + accountStatus: users[0].account_status, + password: "abcde", + }); + expectCall(ormPMock.updatePerson, { + personId: users[0].person_id, + name: "myname", + }); +}); + +test("Can't modify self (invalid old password)", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "abcd", + pass: { oldpass: users[0].password + "__old", newpass: "abcde" }, + name: "myname", + }; + + await expect(user.userModSelf(req)).rejects.toStrictEqual({ + http: 409, + reason: "Old password is incorrect. Didn't update password.", + }); + expectCall(reqMock.parseUserModSelfRequest, req); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.getLoginUserById, 0); + expectCall(utilMock.getOrReject, users[0]); + expect(bcryptMock.compare).toHaveBeenCalledTimes(1); + expect(ormLUMock.updateLoginUser).not.toHaveBeenCalled(); + expect(ormPMock.updatePerson).not.toHaveBeenCalled(); +}); + +test("Can get current user", async () => { + const req = getMockReq(); + + await expect(user.getCurrentUser(req)).resolves.toStrictEqual({ + person: { + person_id: users[0].person.person_id, + name: users[0].person.name, + email: users[0].person.email === null ? "" : users[0].person.email, + github: + users[0].person.github === null ? "" : users[0].person.github, + }, + is_coach: users[0].is_coach, + is_admin: users[0].is_admin, + account_status: users[0].account_status, + login_user_id: users[0].login_user_id, + }); + expectCall(reqMock.parseCurrentUserRequest, req); + expectCall(utilMock.checkSessionKey, { sessionkey: "valid" }); + expectCall(ormLUMock.getLoginUserById, 0); +}); + +test("Can't accept new users (login user is null)", async () => { + ormLUMock.searchLoginUserByPerson.mockReset(); + ormLUMock.searchLoginUserByPerson.mockResolvedValue(null); + + const req = getMockReq(); + req.body = { sessionkey: "key", id: 1, is_admin: false, is_coach: false }; + + await expect(user.createUserAcceptance(req)).rejects.toStrictEqual( + undefined + ); + expectCall(reqMock.parseAcceptNewUserRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.mutable).toHaveBeenCalledTimes(1); + expect(ormLU.searchLoginUserByPerson).toHaveBeenCalledTimes(1); +}); + +test("Can't reject new users (login user is null)", async () => { + ormLUMock.searchLoginUserByPerson.mockReset(); + ormLUMock.searchLoginUserByPerson.mockResolvedValue(null); + + const req = getMockReq(); + req.body = { sessionkey: "key", id: 1, is_admin: false, is_coach: false }; + + await expect(user.deleteUserRequest(req)).rejects.toStrictEqual(undefined); + expectCall(reqMock.parseAcceptNewUserRequest, req); + expectCall(utilMock.isAdmin, req.body); + expect(utilMock.mutable).toHaveBeenCalledTimes(1); + expect(ormLU.searchLoginUserByPerson).toHaveBeenCalledTimes(1); +}); + +test("Can modify self (no pass change)", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "abcd", + name: "myname", + }; + + await expect(user.userModSelf(req)).resolves.toStrictEqual({ + sessionkey: "abcd", + }); + expectCall(reqMock.parseUserModSelfRequest, req); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.getLoginUserById, 0); + expectCall(utilMock.getOrReject, users[0]); + expect(bcryptMock.compare).toHaveBeenCalledTimes(0); + expect(ormLUMock.updateLoginUser).not.toHaveBeenCalled(); + expectCall(ormPMock.updatePerson, { + personId: users[0].person_id, + name: "myname", + }); +}); + +test("Can modify self (no name change)", async () => { + const req = getMockReq(); + req.body = { + sessionkey: "abcd", + pass: { oldpass: users[0].password, newpass: "abcde" }, + }; + + await expect(user.userModSelf(req)).resolves.toStrictEqual({ + sessionkey: "abcdefghijklmnopqrstuvwxyz", + }); + expectCall(reqMock.parseUserModSelfRequest, req); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.getLoginUserById, 0); + expectCall(utilMock.getOrReject, users[0]); + expect(bcryptMock.compare).toHaveBeenCalledTimes(1); + expectCall(ormLUMock.updateLoginUser, { + loginUserId: 0, + accountStatus: users[0].account_status, + password: "abcde", + }); + expect(ormPMock.updatePerson).not.toHaveBeenCalled(); +}); + +test("Create user permission", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "abcd", + osoc_id: 0, + login_user_id: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseUsersPermissionsRequest.mockResolvedValue({ + sessionkey: "abcd", + osoc_id: 0, + login_user_id: 0, + id: 0, + }); + + ormLuOsMock.addOsocToUser.mockResolvedValue({ + login_user_osoc_id: 0, + login_user_id: 0, + osoc_id: 0, + }); + + await expect(user.createUserPermission(req)).resolves.toStrictEqual({}); + + reqMock.parseUsersPermissionsRequest.mockReset(); + ormLuOsMock.addOsocToUser.mockReset(); +}); + +test("Delete user permission", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "abcd", + osoc_id: 0, + login_user_id: 0, + }; + + req.params.id = id.toString(); + + reqMock.parseUsersPermissionsRequest.mockResolvedValue({ + sessionkey: "abcd", + osoc_id: 0, + login_user_id: 0, + id: 0, + }); + + ormLuOsMock.removeOsocFromUser.mockResolvedValue({ + count: 1, + }); + + await expect(user.deleteUserPermission(req)).resolves.toStrictEqual({}); + + reqMock.parseUsersPermissionsRequest.mockReset(); + ormLuOsMock.removeOsocFromUser.mockReset(); +}); + +test("Get year permissions, no admin", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "abcd", + }; + + req.params.id = id.toString(); + + utilMock.isAdmin.mockImplementation((v) => { + return Promise.resolve({ + data: v, + userId: 7, + accountStatus: "ACTIVATED", + is_admin: false, + is_coach: true, + }); + }); + + await expect(user.getYearPermissions(req)).rejects.toBe( + errors.cookInsufficientRights() + ); + + utilMock.isAdmin.mockReset(); +}); + +test("Get year permissions, no admin", async () => { + const req = getMockReq(); + const id = 0; + req.body = { + sessionkey: "abcd", + }; + + req.params.id = id.toString(); + + reqMock.parseGetUserPermissionsRequest.mockResolvedValue({ + sessionkey: "abcd", + id: 0, + }); + + ormLuOsMock.getOsocYearsForLoginUserById.mockResolvedValue([ + { + login_user_osoc_id: 0, + login_user_id: 0, + osoc_id: 0, + osoc: { + osoc_id: 0, + year: 2022, + }, + }, + ]); + + await expect(user.getYearPermissions(req)).resolves.toStrictEqual([ + { + osoc_id: 0, + year: 2022, + }, + ]); + + reqMock.parseGetUserPermissionsRequest.mockReset(); + ormLuOsMock.getOsocYearsForLoginUserById.mockReset(); +}); diff --git a/backend/tests/routes_unit/verify.test.ts b/backend/tests/routes_unit/verify.test.ts new file mode 100644 index 00000000..ba122b86 --- /dev/null +++ b/backend/tests/routes_unit/verify.test.ts @@ -0,0 +1,77 @@ +// only test successes because +// 1: checkSessionKey/isAdmin has been tested +// 2: orm functions are fully tested +// 3: respOrError has been tested +// 4: all parsers have been tested +// -> failures use those stacks and aren't usually caught in the routes +// -> if those stacks work, all failures work as well (because Promises). + +import { getMockReq } from "@jest-mock/express"; +import { account_status_enum } from "@prisma/client"; + +// setup mock for request +import * as req from "../../request"; +jest.mock("../../request"); +const reqMock = req as jest.Mocked; + +// setup mock for utility +import * as util from "../../utility"; +jest.mock("../../utility"); +const utilMock = util as jest.Mocked; + +import * as verify from "../../routes/verify"; + +const okay = { + valid: true, + is_coach: true, + is_admin: true, + accountStatus: "ACTIVATED" as account_status_enum, + userId: 0, +}; + +beforeEach(() => { + utilMock.checkSessionKey.mockImplementation((v) => { + if (v.sessionkey == "abcd") + return Promise.resolve({ ...okay, data: v }); + return Promise.reject({}); + }); + + reqMock.parseVerifyRequest.mockImplementation((v) => v.body); +}); + +afterEach(() => { + utilMock.checkSessionKey.mockReset(); + reqMock.parseVerifyRequest.mockReset(); +}); + +function expectCall(func: T, val: U) { + expect(func).toHaveBeenCalledTimes(1); + expect(func).toHaveBeenCalledWith(val); +} + +test("Can verify a valid key", async () => { + const req = getMockReq(); + req.body = { sessionkey: "abcd" }; + + await expect(verify.verifyKey(req)).resolves.toStrictEqual({ + valid: true, + is_coach: true, + is_admin: true, + account_status: "ACTIVATED", + }); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(1); + expect(utilMock.checkSessionKey).toHaveBeenCalledWith(req.body, false); + expectCall(reqMock.parseVerifyRequest, req); +}); + +test("Can verify an invalid key", async () => { + const req = getMockReq(); + req.body = { sessionkey: "abc" }; + + await expect(verify.verifyKey(req)).resolves.toStrictEqual({ + valid: false, + }); + expect(utilMock.checkSessionKey).toHaveBeenCalledTimes(1); + expect(utilMock.checkSessionKey).toHaveBeenCalledWith(req.body, false); + expectCall(reqMock.parseVerifyRequest, req); +}); diff --git a/backend/tests/tests-setup.ts b/backend/tests/tests-setup.ts index b167b406..5ef50011 100644 --- a/backend/tests/tests-setup.ts +++ b/backend/tests/tests-setup.ts @@ -1,3 +1,4 @@ import dotenv from "dotenv"; import path from "path"; dotenv.config({ path: path.resolve(__dirname + "./../prisma/.env.test") }); +jest.useFakeTimers("legacy"); diff --git a/backend/tests/utility.test.ts b/backend/tests/utility.test.ts index f7e06fee..1e234db0 100644 --- a/backend/tests/utility.test.ts +++ b/backend/tests/utility.test.ts @@ -28,6 +28,10 @@ import * as project from "../orm_functions/project"; jest.mock("../orm_functions/project"); const projectMock = project as jest.Mocked; +import * as osoc from "../orm_functions/osoc"; +jest.mock("../orm_functions/osoc"); +const osocMock = osoc as jest.Mocked; + import * as crypto from "crypto"; jest.mock("crypto"); const cryptoMock = crypto as jest.Mocked; @@ -35,29 +39,19 @@ const cryptoMock = crypto as jest.Mocked; import * as config from "../config.json"; import { ApiError, Anything } from "../types"; import * as util from "../utility"; -import { errors } from "../utility"; +import { + checkYearPermissionOsoc, + checkYearPermissionProject, + checkYearPermissionStudent, + errors, +} from "../utility"; +import { account_status_enum } from "@prisma/client"; interface Req { url: string; verb: string; } -function genPromises(): Promise[] { - const data: unknown[] = [ - 6, - "abc", - { key: "value" }, - { complex: { object: "with", array: [1, 2, 3, 4] } }, - ]; - const promises: Promise[] = data.map((val) => - util.debug(val).then((res) => { - expect(res).toBe(val); - return res; - }) - ); - return promises; -} - function obtainResponse() { const { res } = getMockRes(); const statSpy = jest.spyOn(res, "status"); @@ -74,6 +68,9 @@ test("utility.errors.cook* work as expected", () => { expect(util.errors.cookUnauthenticated()).toBe( config.apiErrors.unauthenticated ); + expect(util.errors.cookWrongSuggestionYear()).toBe( + config.apiErrors.studentSuggestion.insufficientRights + ); expect(util.errors.cookInsufficientRights()).toBe( config.apiErrors.insufficientRights ); @@ -84,6 +81,9 @@ test("utility.errors.cook* work as expected", () => { expect(util.errors.cookPendingAccount()).toBe( config.apiErrors.pendingAccount ); + expect(util.errors.cookWrongOsocYear()).toBe( + config.apiErrors.modifyProject.insufficientRights + ); // annoying ones // non-existent endpoint @@ -158,19 +158,6 @@ test("utility.errors.cook* work as expected", () => { ); }); -test("utility.debug returns identical", () => { - return Promise.all(genPromises()); -}); - -test("utility.debug logs their data", () => { - const logSpy = jest.spyOn(console, "log"); - return Promise.all( - genPromises().map((it) => - it.then((val) => expect(logSpy).toHaveBeenCalledWith(val)) - ) - ); -}); - test("utility.reply writes to a response", () => { const data: { status: number; data: unknown }[] = [ { status: 200, data: "success!" }, @@ -255,8 +242,6 @@ test("utility.addInvalidVerbs adds verbs", () => { expect(routerSpy).toHaveBeenCalledTimes(1); }); -// we need to check line_#117 but I have no idea on how to do that... - test("utility.logRequest logs request and passes control", () => { const writeSpy = jest.spyOn(console, "log"); const request: express.Request = getMockReq(); @@ -376,8 +361,7 @@ test("utility.checkSessionKey works on valid session key", async () => { is_coach: false, account_status: "ACTIVATED", person: { - firstname: "Bob", - lastname: "Test", + name: "Bob", email: "bob.test@mail.com", github: "bob.test@github.com", person_id: 987654321, @@ -401,7 +385,7 @@ test("utility.checkSessionKey works on valid session key", async () => { expect(session_keyMock.checkSessionKey).toHaveBeenCalledWith("key"); }); -test("utility.checkSessionKey fails on valid session key (pending)", async () => { +test("utility.checkSessionKey test_fails on valid session key (pending)", async () => { login_userMock.getLoginUserById.mockReset(); session_keyMock.checkSessionKey.mockReset(); login_userMock.getLoginUserById.mockResolvedValue({ @@ -412,8 +396,7 @@ test("utility.checkSessionKey fails on valid session key (pending)", async () => is_coach: false, account_status: "PENDING", person: { - firstname: "Bob", - lastname: "Test", + name: "Bob", email: "bob.test@mail.com", github: "bob.test@github.com", person_id: 987654321, @@ -443,8 +426,7 @@ test("utility.checkSessionKey works on valid session key (pending,false)", async is_coach: false, account_status: "PENDING", person: { - firstname: "Bob", - lastname: "Test", + name: "Bob", email: "bob.test@mail.com", github: "bob.test@github.com", person_id: 987654321, @@ -468,7 +450,67 @@ test("utility.checkSessionKey works on valid session key (pending,false)", async expect(session_keyMock.checkSessionKey).toHaveBeenCalledWith("key"); }); -test("utility.checkSessionKey fails on invalid session key", async () => { +test("utility.checkSessionKey test_fails on valid session key (disabled)", async () => { + login_userMock.getLoginUserById.mockReset(); + session_keyMock.checkSessionKey.mockReset(); + login_userMock.getLoginUserById.mockResolvedValue({ + login_user_id: 123456789, + person_id: 987654321, + password: "pass", + is_admin: true, + is_coach: false, + account_status: "DISABLED", + person: { + name: "Bob", + email: "bob.test@mail.com", + github: "bob.test@github.com", + person_id: 987654321, + github_id: "46845", + }, + }); + session_keyMock.checkSessionKey.mockResolvedValue({ + login_user_id: 123456789, + }); + const obj = { sessionkey: "key" }; + + await expect(util.checkSessionKey(obj)).rejects.toStrictEqual( + errors.cookLockedRequest() + ); + expect(session_keyMock.checkSessionKey).toHaveBeenCalledTimes(1); + expect(session_keyMock.checkSessionKey).toHaveBeenCalledWith("key"); +}); + +test("utility.checkSessionKey test_fails on valid session key (disabled, false)", async () => { + login_userMock.getLoginUserById.mockReset(); + session_keyMock.checkSessionKey.mockReset(); + login_userMock.getLoginUserById.mockResolvedValue({ + login_user_id: 123456789, + person_id: 987654321, + password: "pass", + is_admin: true, + is_coach: false, + account_status: "DISABLED", + person: { + name: "Bob", + email: "bob.test@mail.com", + github: "bob.test@github.com", + person_id: 987654321, + github_id: "46845", + }, + }); + session_keyMock.checkSessionKey.mockResolvedValue({ + login_user_id: 123456789, + }); + const obj = { sessionkey: "key" }; + + await expect(util.checkSessionKey(obj, false)).rejects.toStrictEqual( + errors.cookLockedRequest() + ); + expect(session_keyMock.checkSessionKey).toHaveBeenCalledTimes(1); + expect(session_keyMock.checkSessionKey).toHaveBeenCalledWith("key"); +}); + +test("utility.checkSessionKey test_fails on invalid session key (1)", async () => { session_keyMock.checkSessionKey.mockReset(); session_keyMock.checkSessionKey.mockRejectedValue(new Error()); @@ -482,6 +524,33 @@ test("utility.checkSessionKey fails on invalid session key", async () => { expect(session_keyMock.checkSessionKey).toHaveBeenCalledWith("key"); }); +test("utility.checkSessionKey test_fails on invalid session key (2)", async () => { + session_keyMock.checkSessionKey.mockReset(); + session_keyMock.checkSessionKey.mockResolvedValue(null); + + await expect( + util.checkSessionKey({ + sessionkey: "key", + }) + ).rejects.toStrictEqual(util.errors.cookUnauthenticated()); + + expect(session_keyMock.checkSessionKey).toHaveBeenCalledTimes(1); + expect(session_keyMock.checkSessionKey).toHaveBeenCalledWith("key"); +}); + +test("utility.checkSessionKey test_fails on non-existent users", async () => { + login_userMock.getLoginUserById.mockReset(); + login_userMock.getLoginUserById.mockResolvedValue(null); + session_keyMock.checkSessionKey.mockReset(); + session_keyMock.checkSessionKey.mockResolvedValue({ + login_user_id: 123456, + }); + + return expect( + util.checkSessionKey({ sessionkey: "123" }, false) + ).rejects.toStrictEqual(errors.cookUnauthenticated()); +}); + test( "utility.isAdmin should succeed on valid keys, fail on invalid keys" + "and fail on non-admin keys", @@ -507,8 +576,7 @@ test( is_coach: false, account_status: "ACTIVATED", person: { - firstname: "firstname", - lastname: "lastname", + name: "firstname", email: "email@hotmail.com", github: "hiethub", person_id: 1, @@ -523,8 +591,7 @@ test( is_coach: false, account_status: "ACTIVATED", person: { - firstname: "firstname", - lastname: "lastname", + name: "firstname", email: "email@mail.com", github: "hiethub", person_id: 0, @@ -547,8 +614,7 @@ test( is_coach: false, account_status: "ACTIVATED", person: { - lastname: "lastname", - firstname: "firstname", + name: "firstname", github: "hiethub", person_id: 0, email: "email@mail.com", @@ -603,13 +669,165 @@ test("utility.isAdmin can catch errors from the DB", async () => { Promise.reject({}) ); - expect( + await expect( util.isAdmin({ sessionkey: "key", }) ).rejects.toStrictEqual(util.errors.cookInsufficientRights()); }); +test("the student is visible for the loginUser", async () => { + studentMock.getAppliedYearsForStudent.mockReset(); + studentMock.getAppliedYearsForStudent.mockResolvedValue( + Promise.resolve([2022]) + ); + login_userMock.getOsocYearsForLoginUser.mockReset(); + login_userMock.getOsocYearsForLoginUser.mockResolvedValue( + Promise.resolve([2022]) + ); + + const inputObj = { + data: { + id: 0, + sessionkey: "", + }, + userId: 0, + is_coach: false, + is_admin: true, + accountStatus: account_status_enum.DISABLED, + }; + + await expect(checkYearPermissionStudent(inputObj)).resolves.toEqual( + inputObj + ); +}); + +test("the student is NOT visible for the loginUser", async () => { + studentMock.getAppliedYearsForStudent.mockReset(); + studentMock.getAppliedYearsForStudent.mockResolvedValue( + Promise.resolve([2022]) + ); + login_userMock.getOsocYearsForLoginUser.mockReset(); + login_userMock.getOsocYearsForLoginUser.mockResolvedValue( + Promise.resolve([2021]) + ); + + const inputObj = { + data: { + id: 0, + sessionkey: "", + }, + userId: 0, + is_coach: false, + is_admin: true, + accountStatus: account_status_enum.DISABLED, + }; + + await expect(checkYearPermissionStudent(inputObj)).rejects.toBe( + errors.cookInsufficientRights() + ); +}); + +test("the project is visible for the loginUser", async () => { + login_userMock.getOsocYearsForLoginUser.mockReset(); + login_userMock.getOsocYearsForLoginUser.mockResolvedValue( + Promise.resolve([2022]) + ); + projectMock.getProjectYear.mockReset(); + projectMock.getProjectYear.mockResolvedValue(Promise.resolve(2022)); + + const inputObj = { + data: { + id: 0, + sessionkey: "", + }, + userId: 0, + is_coach: false, + is_admin: true, + accountStatus: account_status_enum.DISABLED, + }; + + await expect(checkYearPermissionProject(inputObj)).resolves.toEqual( + inputObj + ); +}); + +test("the project is NOT visible for the loginUser", async () => { + login_userMock.getOsocYearsForLoginUser.mockReset(); + login_userMock.getOsocYearsForLoginUser.mockResolvedValue( + Promise.resolve([2022]) + ); + projectMock.getProjectYear.mockReset(); + projectMock.getProjectYear.mockResolvedValue(Promise.resolve(2021)); + + const inputObj = { + data: { + id: 0, + sessionkey: "", + }, + userId: 0, + is_coach: false, + is_admin: true, + accountStatus: account_status_enum.DISABLED, + }; + + await expect(checkYearPermissionProject(inputObj)).rejects.toBe( + errors.cookInsufficientRights() + ); +}); + +test("the osoc edition is visible for the loginUser", async () => { + login_userMock.getOsocYearsForLoginUser.mockReset(); + login_userMock.getOsocYearsForLoginUser.mockResolvedValue( + Promise.resolve([2022]) + ); + osocMock.getOsocById.mockReset(); + osocMock.getOsocById.mockResolvedValue({ + osoc_id: 0, + year: 2022, + }); + + const inputObj = { + data: { + id: 0, + sessionkey: "", + }, + userId: 0, + is_coach: false, + is_admin: true, + accountStatus: account_status_enum.DISABLED, + }; + + await expect(checkYearPermissionOsoc(inputObj)).resolves.toEqual(inputObj); +}); + +test("the osoc edition is NOT visible for the loginUser", async () => { + login_userMock.getOsocYearsForLoginUser.mockReset(); + login_userMock.getOsocYearsForLoginUser.mockResolvedValue( + Promise.resolve([2022]) + ); + osocMock.getOsocById.mockReset(); + osocMock.getOsocById.mockResolvedValue({ + osoc_id: 0, + year: 2021, + }); + + const inputObj = { + data: { + id: 0, + sessionkey: "", + }, + userId: 0, + is_coach: false, + is_admin: true, + accountStatus: account_status_enum.DISABLED, + }; + + await expect(checkYearPermissionOsoc(inputObj)).rejects.toBe( + errors.cookInsufficientRights() + ); +}); + test("utility.refreshKey removes a key and replaces it", async () => { session_keyMock.refreshKey.mockReset(); @@ -776,10 +994,7 @@ test("utility.addAllInvalidVerbs adds multiple callbacks", () => { test("utility.route installs exactly one route", async () => { const router = getMockRouter(); - const cb = () => { - console.log("RETURNING"); - return Promise.resolve({ sessionkey: "abcd", data: {} }); - }; + const cb = () => Promise.resolve({ sessionkey: "abcd", data: {} }); const path = "/"; const verb = "get"; @@ -817,49 +1032,6 @@ test("utility.route installs exactly one route", async () => { ).rejects.toStrictEqual(getInvalidVerbEndpointError("post", "/")); }); -test("utility.routeKeyOnly installs exactly one route", async () => { - const router = getMockRouter(); - const cb = () => { - console.log("RETURNING"); - return Promise.resolve({ sessionkey: "abcd", data: {} }); - }; - const path = "/"; - const verb = "get"; - - util.routeKeyOnly(router, verb, path, cb); - - // correct - const req1 = getMockReq(); - const res1 = getMockRes().res; - req1.path = path; - req1.method = verb; - - // shouldn't throw - await Promise.resolve() - .then(() => router(req1, res1)) - .then(() => { - expect(res1.status).toHaveBeenCalledWith(200); - }); - - // incorrect ep - const req2 = getMockReq(); - const res2 = getMockRes().res; - req2.path = "/test"; - req2.method = "get"; - expect( - Promise.resolve().then(() => router(req2, res2)) - ).rejects.toStrictEqual(getInvalidEndpointError("/test")); - - // incorrect verb/ep - const req3 = getMockReq(); - const res3 = getMockRes().res; - req3.path = path; - req3.method = "post"; - expect( - Promise.resolve().then(() => router(req3, res3)) - ).rejects.toStrictEqual(getInvalidVerbEndpointError("post", "/")); -}); - test("utility.isValidID checks IDs", async () => { studentMock.getStudent.mockReset(); projectMock.getProjectById.mockReset(); @@ -879,8 +1051,7 @@ test("utility.isValidID checks IDs", async () => { email: null, github: null, github_id: null, - firstname: "jeffrey", - lastname: "jan", + name: "jeffrey jan", }, }); } @@ -898,6 +1069,10 @@ test("utility.isValidID checks IDs", async () => { start_date: new Date(Date.now()), end_date: new Date(Date.now()), positions: 42069, + osoc: { + osoc_id: 516645164126546, + year: 2022, + }, }); } return Promise.resolve(null); @@ -966,6 +1141,39 @@ test("utility.setupRedirect sets up a single redirect", async () => { ); }); +test("utility.queryToBody copies queries to body", () => { + const req = getMockReq(); + const query = { key: "value", key2: "value2" }; + req.query = { ...query }; + req.body = {}; + + util.queryToBody(req); + expect(req.body).toStrictEqual(query); + expect(req.query).toStrictEqual(query); +}); + +test("utility.queryToBody: query has priority over body", () => { + const req = getMockReq(); + const query = { key: "value", key2: "value2" }; + req.query = { ...query }; + req.body = { key: "othervalue" }; + + util.queryToBody(req); + expect(req.body).toStrictEqual(query); + expect(req.query).toStrictEqual(query); +}); + +test("utility.queryToBody can handle empty query", () => { + const req = getMockReq(); + const query = {}; + req.query = { ...query }; + req.body = { key: "othervalue" }; + + util.queryToBody(req); + expect(req.body).toStrictEqual({ key: "othervalue" }); + expect(req.query).toStrictEqual({}); +}); + test("utility.mutable should check if a user is mutable", async () => { expect(util.mutable("str", config.global.defaultUserId)).rejects.toBe( errors.cookInvalidID() diff --git a/backend/tests/utility_unmocked.test.ts b/backend/tests/utility_unmocked.test.ts new file mode 100644 index 00000000..8b747c2a --- /dev/null +++ b/backend/tests/utility_unmocked.test.ts @@ -0,0 +1,10 @@ +import { generateKey } from "../utility"; + +test("utility.generateKey doesn't generate the same key (250 tries)", () => { + const keys = []; + while (keys.length < 250) { + const next = generateKey(); + expect(keys.includes(next)).toBeFalsy(); + keys.push(next); + } +}); diff --git a/backend/tools/curly.sh b/backend/tools/curly.sh index d5ba9c90..5d53aed7 100755 --- a/backend/tools/curly.sh +++ b/backend/tools/curly.sh @@ -16,8 +16,8 @@ function help() { function main() { printf 'Endpoint to access (or -h for help)? ' read ep - if [[ $ep = '-h' ]]; then help $1; exit 0; fi - if [[ $2 = '-no' ]]; then api=''; else api='/api-osoc'; fi + if [[ "$ep" = '-h' ]]; then help; exit 0; fi + if [[ "$2" = '-no' ]]; then api=''; else api='/api-osoc'; fi printf 'HTTP Verb? ' read verb @@ -37,9 +37,9 @@ function main() { while read key; do printf 'Value? ' read value - if [[ $args = '' ]]; then + if [[ "$args" = '' ]]; then args="\"$key\": \"$value\"" - elif [[ ${value:0:1} = '{' ]]; then + elif [[ "${value:0:1}" = '{' ]]; then # send JSON objects correctly args="$args, \"$key\": $value" echo "Will send '$value' as JSON-object" @@ -54,14 +54,14 @@ function main() { echo "Curl command: \`curl -X \"$verb\" \"http://localhost:4096$api$ep\" -i -d $args $skey -H \"Content-Type: application/json\"\`" printf 'Send this curl command (yes/y/no/n/maybe)? ' read ans - while [ $ans != 'yes' ] && [ $ans != 'no' ] && [ $ans != 'maybe' ] && [ $ans != 'y' ] && [ $ans != 'n' ]; do + while [ "$ans" != 'yes' ] && [ "$ans" != 'no' ] && [ "$ans" != 'maybe' ] && [ "$ans" != 'y' ] && [ "$ans" != 'n' ]; do printf 'Invalid answer. Send this curl command (yes/y/no/n/maybe)? ' read ans done - if [ $ans = 'y' ] || [ $ans = 'yes' ]; then + if [ "$ans" = 'y' ] || [ "$ans" = 'yes' ]; then /bin/sh -c "curl -X \"$verb\" \"http://localhost:4096$api$ep\" -i -d $args $skey -H \"Content-Type: application/json\"" - elif [ $ans = 'maybe' ]; then + elif [ "$ans" = 'maybe' ]; then printf 'Output file? ' read f echo "#!/bin/sh" >f diff --git a/backend/tools/dbdump.sh b/backend/tools/dbdump.sh index 8fb24bca..471663b5 100755 --- a/backend/tools/dbdump.sh +++ b/backend/tools/dbdump.sh @@ -14,7 +14,7 @@ function help() { } function main() { - if [ $2 = '-h' ]; then help $1; return 0; fi + if [ "$1" = '-h' ]; then help "$0"; return 0; fi id=`docker ps | grep 'osoc-2-db-1' | cut -d' ' -f1` docker exec -it $id /bin/sh -c "psql -U osoc2 -c \"table $2;\"" diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 590c99a6..6c7af6f2 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -6,7 +6,7 @@ "resolveJsonModule": true }, "typedocOptions": { - "entryPoints": ["orm_functions/applied_role.ts","orm_functions/attachment.ts","orm_functions/contract.ts","orm_functions/evaluation.ts","orm_functions/files","orm_functions/general_purpose.ts","orm_functions/job_application.ts","orm_functions/job_application_skill.ts","orm_functions/language.ts","orm_functions/login_user.ts","orm_functions/orm_types.ts","orm_functions/osoc.ts","orm_functions/password_reset.ts","orm_functions/person.ts","orm_functions/project.ts","orm_functions/project_role.ts","orm_functions/project_user.ts","orm_functions/role.ts","orm_functions/session_key.ts","orm_functions/student.ts","orm_functions/template.ts","routes/admin.ts","routes/coach.ts","routes/files","routes/followup.ts","routes/form.ts","routes/form_keys.json","routes/github.ts","routes/login.ts","routes/project.ts","routes/reset.ts","routes/role.ts","routes/session_key.json","routes/student.ts","routes/template.ts","routes/user.ts","routes/verify.ts"], + "entryPoints": ["routes/admin.ts", "routes/coach.ts", "routes/followup.ts", "routes/form.ts", "routes/github.ts", "routes/login.ts", "routes/osoc.ts", "routes/project.ts", "routes/reset.ts", "routes/role.ts", "routes/student.ts", "routes/template.ts", "routes/user.ts", "routes/verify.ts", "orm_functions/applied_role.ts", "orm_functions/attachment.ts", "orm_functions/contract.ts", "orm_functions/evaluation.ts", "orm_functions/general_purpose.ts", "orm_functions/job_application_skill.ts", "orm_functions/job_application.ts", "orm_functions/language.ts", "orm_functions/login_user_osoc.ts", "orm_functions/login_user.ts", "orm_functions/orm_types.ts", "orm_functions/osoc.ts", "orm_functions/password_reset.ts", "orm_functions/person.ts", "orm_functions/project_role.ts", "orm_functions/project_user.ts", "orm_functions/project.ts", "orm_functions/role.ts", "orm_functions/session_key.ts", "orm_functions/student.ts", "orm_functions/template.ts"], "out": "docs" } } diff --git a/backend/typedoc.json b/backend/typedoc.json index e8e79f35..da5d9764 100644 --- a/backend/typedoc.json +++ b/backend/typedoc.json @@ -1,4 +1,4 @@ { - "entryPoints": ["routes/admin.ts", "routes/coach.ts", "routes/form.ts", "routes/login.ts", "routes/project.ts", "routes/student.ts","orm_functions/applied_role.ts", "orm_functions/job_application.ts", "orm_functions/osoc.ts", "orm_functions/role.ts", "orm_functions/attachment.ts", "orm_functions/job_application_skill.ts", "orm_functions/person.ts", "orm_functions/session_key.ts", "orm_functions/contract.ts", "orm_functions/language.ts", "orm_functions/project.ts", "orm_functions/student.ts", "orm_functions/evaluation.ts", "orm_functions/login_user.ts", "orm_functions/project_role.ts", "orm_functions/general_purpose.ts", "orm_functions/orm_types.ts", "orm_functions/project_user.ts"], + "entryPoints": ["routes/admin.ts", "routes/coach.ts", "routes/followup.ts", "routes/form.ts", "routes/github.ts", "routes/login.ts", "routes/osoc.ts", "routes/project.ts", "routes/reset.ts", "routes/role.ts", "routes/student.ts", "routes/template.ts", "routes/user.ts", "routes/verify.ts", "orm_functions/applied_role.ts", "orm_functions/attachment.ts", "orm_functions/contract.ts", "orm_functions/evaluation.ts", "orm_functions/general_purpose.ts", "orm_functions/job_application_skill.ts", "orm_functions/job_application.ts", "orm_functions/language.ts", "orm_functions/login_user_osoc.ts", "orm_functions/login_user.ts", "orm_functions/orm_types.ts", "orm_functions/osoc.ts", "orm_functions/password_reset.ts", "orm_functions/person.ts", "orm_functions/project_role.ts", "orm_functions/project_user.ts", "orm_functions/project.ts", "orm_functions/role.ts", "orm_functions/session_key.ts", "orm_functions/student.ts", "orm_functions/template.ts"], "out": "docs" } diff --git a/backend/types.ts b/backend/types.ts index 191c4924..4402932e 100644 --- a/backend/types.ts +++ b/backend/types.ts @@ -1,7 +1,11 @@ import { account_status_enum, + contract_status_enum, + decision_enum, email_status_enum, type_enum, + person, + project_user, } from "@prisma/client"; import express from "express"; import { FilterSort } from "./orm_functions/orm_types"; @@ -46,6 +50,14 @@ export interface Errors { * Cooks up a locked request response. */ cookLockedRequest: () => ApiError; + /** + * Cooks up a wrong suggestion request response. + */ + cookWrongSuggestionYear: () => ApiError; + /** + * Cooks up a wrong osoc request response. + */ + cookWrongOsocYear: () => ApiError; /** * Cooks up a Non-existent Endpoint response. * @param url The requested endpoint URL. @@ -91,7 +103,28 @@ export namespace InternalTypes { */ export type Suggestion = "YES" | "MAYBE" | "NO"; - export interface SuggestionInfo {} + export interface SuggestionInfo { + /** + * The evaluation id. + */ + evaluation_id: number; + /** + * The name of the login user. + */ + senderName: string | undefined; + /** + * The reason why the decision was made. + */ + reason: string | null; + /** + * The ID. + */ + decision: decision_enum; + /** + * The ID. + */ + isFinal: boolean; + } /** * Represents a response that only contains an ID. @@ -103,6 +136,11 @@ export namespace InternalTypes { id: number; } + export interface Role { + role_id: number; + name: string; + } + /** * Represents a partial type response. Usually these will only contain a name * and an ID. @@ -123,13 +161,9 @@ export namespace InternalTypes { */ person_id: number; /** - * The firstname of this person. - */ - firstname: string; - /** - * The lastname of this person. + * The name of this person. */ - lastname: string; + name: string; /** * The email of this person. */ @@ -141,13 +175,9 @@ export namespace InternalTypes { */ export interface FormPerson { /** - * The firstname of this person. + * The name of this person. */ - birthName: string; - /** - * The lastname of this person. - */ - lastName: string; + name: string; /** * The email of this person. */ @@ -158,18 +188,363 @@ export namespace InternalTypes { * Represents a student, with all associated data. Does not correspond to a * student in the database. */ - export interface Student {} + export interface Student { + student: StudentField | null; + jobApplication: StudentJobApplication | undefined; + evaluation: StudentEvaluation | undefined; + evaluations: StudentsAllEvaluations[] | undefined; + roles: string[] | undefined; + } + + /** + * The person entity for a student + */ + interface StudentPerson { + /** + * The name of this student. + */ + name: string; + /** + * The person id of this student. + */ + person_id: number; + /** + * The email of this student. + */ + email: string | null; + /** + * The GitHub of this student. + */ + github: string | null; + /** + * The GitHub id of this student. + */ + github_id: string | null; + } + + /** + * The student entity for a student + */ + interface StudentField { + /** + * The student id of this student. + */ + student_id: number; + /** + * The person id of this student. + */ + person_id: number | undefined; + /** + * The person fields. + */ + person: StudentPerson; + /** + * The alumni status of this student. + */ + alumni: boolean; + /** + * The nickname of this student. + */ + nickname: string | null; + /** + * The gender of this student. + */ + gender: string; + /** + * The pronouns of this student. + */ + pronouns: string | null; + /** + * The phone number of this student. + */ + phone_number: string; + } + + /** + * A student job application. + */ + interface StudentJobApplication { + /** + * The job application id + */ + job_application_id: number; + /** + * The id of this student + */ + student_id: number | null; + /** + * The id of the osoc edition + */ + osoc_id: number; + /** + * The responsibilities + */ + responsibilities: string | null; + /** + * The date + */ + created_at: Date; + /** + * The duration + */ + edu_duration: number | null; + /** + * The institute of the student + */ + edu_institute: string | null; + /** + * The level of the education of this student + */ + edu_level: string; + /** + * The education year + */ + edu_year: string | null; + /** + * The educations of the student + */ + edus: string[]; + /** + * The email status of the student + */ + email_status: email_status_enum; + /** + * The fun fact + */ + fun_fact: string; + /** + * True if this student wants to be a student-coach, else false + */ + student_coach: boolean; + /** + * The volunteer info + */ + student_volunteer_info: string; + /** + * The job application skills + */ + job_application_skill: StudentJobApplicationSkill[]; + /** + * The job application applied roles + */ + applied_role: StudentAppliedRole[]; + /** + * The job application attachments + */ + attachment: StudentAttachment[]; + } + + /** + * The job application skill. + */ + interface StudentJobApplicationSkill { + /** + * The skill + */ + skill: string | null; + /** + * The id of the job application + */ + job_application_id: number; + /** + * The id of the skill + */ + job_application_skill_id: number; + /** + * The id of the language + */ + language_id: number | null; + /** + * True if this skill is the best skill, else false + */ + is_best: boolean; + /** + * True if this skill is the preferred skill, else false + */ + is_preferred: boolean; + /** + * The level of the skill + */ + level: number | null; + } + + /** + * An applied role. + */ + interface StudentAppliedRole { + /** + * The id of the job application + */ + job_application_id: number; + /** + * The id of the role + */ + role_id: number; + /** + * The id of the applied role + */ + applied_role_id: number; + } + + /** + * A job application attachment. + */ + interface StudentAttachment { + /** + * The id of the job application + */ + job_application_id: number; + /** + * The id of the attachment + */ + attachment_id: number; + /** + * The data of the attachment + */ + data: string[]; + /** + * The data types + */ + type: type_enum[]; + } + + /** + * The evaluation + */ + interface StudentEvaluation { + /** + * The id of the evaluation + */ + evaluations: StudentEvaluationsField[]; + osoc: StudentOsocYear; + } + + /** + * The osoc year. + */ + interface StudentOsocYear { + /** + * The osoc year + */ + year: number; + } + + /** + * The evaluation field for /student/all. + */ + interface StudentsAllEvaluations { + /** + * The evaluation + */ + evaluation: StudentsAllEvaluationField[]; + /** + * The osoc year + */ + osoc: StudentOsocYear; + } + + /** + * The evaluation field for /student/all. + */ + interface StudentsAllEvaluationField extends StudentEvaluationsField { + /** + * The id of the evaluation + */ + login_user: StudentEvaluationsLoginUser | null; + } + + /** + * The login user that belongs to an evaluation. + */ + interface StudentEvaluationsLoginUser { + /** + * The id of the login_user + */ + login_user_id: number; + /** + * The person + */ + person: StudentEvaluationsLoginUserPerson; + } + + /** + * The login user (person) that belongs to an evaluation. + */ + interface StudentEvaluationsLoginUserPerson { + /** + * The name of the login user + */ + name: string; + /** + * The person id + */ + person_id: number; + /** + * The email of this login user + */ + email: string | null; + /** + * The GitHub of this login user + */ + github: string | null; + } + + /** + * All student evaluations + */ + export interface AllStudentsEvaluations { + /** + * The evaluations + */ + evaluation: AllStudentsEvaluationsField; + } + + /** + * All student evaluations field + */ + interface AllStudentsEvaluationsField { + /** + * The evaluations + */ + evaluations: StudentsAllEvaluationField[]; + /** + * The osoc year + */ + osoc: StudentOsocYear; + } + + /** + * The evaluations field. + */ + interface StudentEvaluationsField { + /** + * The id of the evaluation + */ + evaluation_id: number; + /** + * The decision + */ + decision: decision_enum; + /** + * The reason of the decision + */ + motivation: string | null; + /** + * True if the decision is final, else false + */ + is_final: boolean; + } /** * Represents a form-student, with all associated data. */ export interface FormStudent { /** - * The firstname of this person. + * The pronouns of this person. */ pronouns: string | null; /** - * The lastname of this person. + * The gender of this person. */ gender: string; /** @@ -289,7 +664,18 @@ export namespace InternalTypes { /** * Represents a user, with all associated data. */ - export interface User {} + export interface User { + person: { + person_id: number; + email: string; + name: string; + github: string; + }; + login_user_id: number; + is_coach: boolean; + is_admin: boolean; + account_status: AccountStatus; + } /** * Represents an osoc edition, with all associated data. @@ -309,6 +695,7 @@ export namespace InternalTypes { coach: boolean; admin: boolean; activated: string; + login_user_id: number; } /** @@ -344,13 +731,64 @@ export namespace InternalTypes { partner: string; start_date: string; end_date: string; - positions: number; + roles: { name: string; positions: number }[]; + description: string | null; + coaches: { + login_user: { + person: person; + login_user_id: number; + is_admin: boolean; + is_coach: boolean; + }; + project_user_id: number; + }[]; } /** * Represents a project, with all associated data. */ - export interface ProjectFilter {} + export interface ProjectAndContracts { + id: number; + name: string; + partner: string; + start_date: string; + end_date: string; + roles: object; + contracts: Contract[]; + coaches: object; + } + + /** + * Represents a contract, with all associated data. + */ + export interface Contract { + project_role: { + project_role_id: number; + project_id: number; + role_id: number; + positions: number; + role: { name: string }; + } | null; + contract_id: number; + contract_status: contract_status_enum; + login_user: { + person: person; + login_user_id: number; + is_admin: boolean; + is_coach: boolean; + } | null; + student: Student; + } + + /** + * Represents a person, with all associated data. + */ + export interface StudentRole { + /** + * The role id. + */ + role_id: number; + } /** * Represents the drafted students of a project. Usually these will only @@ -368,7 +806,55 @@ export namespace InternalTypes { /** * The students. */ - students: Student[]; + students: ProjectStudent[]; + } + + /** + * Represents a student of a project. + */ + interface ProjectStudent { + /** + * The contract status + */ + status: contract_status_enum; + /** + * The student info + */ + student: ProjectStudentField | null; + } + + /** + * The student entity field for a project + */ + interface ProjectStudentField { + /** + * The student id of this student. + */ + student_id: number; + /** + * The person fields. + */ + person: StudentPerson; + /** + * The alumni status of this student. + */ + alumni: boolean; + /** + * The nickname of this student. + */ + nickname: string | null; + /** + * The gender of this student. + */ + gender: string; + /** + * The pronouns of this student. + */ + pronouns: string | null; + /** + * The phone number of this student. + */ + phone_number: string; } /** @@ -412,7 +898,7 @@ export namespace InternalTypes { export interface ShortTemplate { id: number; - owner: number; + owner: number | null; name: string; } @@ -421,7 +907,7 @@ export namespace InternalTypes { } export interface FollowupStatus { - student: number; + student: number | null; status: email_status_enum; application: number; } @@ -440,6 +926,15 @@ export interface WithUserID { * {@link InternalTypes}. The success boolean is added when sending. */ export namespace Responses { + /** + * A paginable response holds, besides a data array, also the current page + * number and the total number of objects in the database + */ + export interface Paginable { + pagination: { page: number; count: number }; + data: T[]; + } + /** * A response consisting of only a session key. */ @@ -457,8 +952,7 @@ export namespace Responses { /** * A response consisting of and id and boolean. */ - export interface Id_alumni { - id: number; + export interface Id_alumni extends Id { hasAlreadyTakenPart: boolean; } @@ -471,6 +965,14 @@ export namespace Responses { is_coach: boolean; } + /** + * A GitHub login response differs from a normal login response by the added + * is_signup field, which should tell the client that this user was newly created. + */ + export interface GithubLogin extends Login { + is_signup: boolean; + } + /** * A partial student response is the keyed combination of their id and name. */ @@ -492,6 +994,11 @@ export namespace Responses { */ export interface Student extends InternalTypes.Student {} + /** + * Represents a contract, with all associated data. + */ + export interface Contract extends InternalTypes.Contract {} + /** * A form-student. */ @@ -514,26 +1021,38 @@ export namespace Responses { */ export interface User extends InternalTypes.User {} + export interface AllStudentEvaluationsResponse + extends InternalTypes.AllStudentsEvaluations {} + /** * A studentList response is the keyed version of a list of students and their * associated data. */ - export interface StudentList { - data: InternalTypes.Student[]; + export interface StudentList extends Paginable {} + + /** + * StudentRoles are a list of roles. + */ + export interface StudentRoles { + data: InternalTypes.StudentRole[]; } /** * */ - export interface UserList { - data: InternalTypes.User[]; + export interface UserList extends Paginable {} + + export interface RoleList { + data: InternalTypes.Role[]; } + export interface ProjectUser extends project_user {} + /** * */ export interface OsocEditionList { - data: InternalTypes.OsocEdition[]; + data: OsocEdition[]; } /** @@ -564,11 +1083,11 @@ export namespace Responses { } /** - * A student response is the keyed version of the student and their associated + * The suggestion info * data. */ export interface SuggestionInfo { - data: InternalTypes.SuggestionInfo[]; + data: InternalTypes.SuggestionInfo; } /** @@ -632,18 +1151,27 @@ export namespace Responses { export interface Project extends InternalTypes.Project {} /** - * A project list response is the keyed version of a list of projects + * A user permission response + * data. */ - export interface ProjectList { - data: InternalTypes.Project[]; + export interface UserYearsPermissions { + osoc_id: number; + year: number; } /** - * A project filter list is a list of projects + * A project list response with contracts in it */ - export interface ProjectFilterList { - data: InternalTypes.ProjectFilter; + export interface ProjectAndContracts + extends InternalTypes.ProjectAndContracts {} + + /** + * A project list response is the keyed version of a list of projects + */ + export interface ProjectListAndContracts { + data: InternalTypes.ProjectAndContracts[]; } + export interface ProjectList extends Paginable {} /** * An admin list response is the keyed version of the list of admins. @@ -674,18 +1202,6 @@ export namespace Responses { data: InternalTypes.Student[]; } - /** - * An EvaluationCoach response. - */ - export interface EvaluationCoach { - evaluation_id: number; - senderFirstname: string; - senderLastname: string; - reason: string | null; - decision: InternalTypes.Suggestion; - isFinal: boolean; - } - /** * A conflictList response is the keyed version of a list of conflicts. */ @@ -711,17 +1227,6 @@ export namespace Responses { */ export type OrError = ApiError | T; - /** - * An API response is one of the previous response types. - * @deprecated Not up to date - */ - export type ApiResponse = - | Empty - | Key - | PartialStudent - | IdNameList - | ConflictList; - /** * Either an error while parsing the form or a data value. */ @@ -734,6 +1239,11 @@ export namespace Responses { } export namespace Requests { + export interface PaginableRequest extends KeyRequest { + currentPage: number; + pageSize: number; // will be filled in by the parser using the config + } + export interface Login { name: string; pass: string; @@ -770,9 +1280,35 @@ export namespace Requests { name?: string; } - export interface StudentFilter extends KeyRequest {} + export interface StudentFilterParameters { + osocYear?: number; + nameFilter?: string; + emailFilter?: string; + roleFilter?: string[] | string; + alumniFilter?: boolean | string; + coachFilter?: boolean | string; + statusFilter?: decision_enum; + emailStatusFilter?: email_status_enum; + nameSort?: string; + emailSort?: string; + alumniSort?: string; + } + + export interface StudentFilter extends PaginableRequest { + osocYear?: number; + nameFilter?: string; + emailFilter?: string; + roleFilter?: string[]; + alumniFilter?: boolean; + coachFilter?: boolean; + statusFilter?: decision_enum; + emailStatusFilter?: email_status_enum; + nameSort?: FilterSort; + emailSort?: FilterSort; + alumniSort?: FilterSort; + } - export interface UserFilter extends KeyRequest { + export interface UserFilter extends PaginableRequest { sessionkey: string; nameFilter?: string; emailFilter?: string; @@ -783,7 +1319,10 @@ export namespace Requests { isAdminFilter?: boolean; } - export interface OsocFilter extends KeyRequest {} + export interface OsocFilter extends PaginableRequest { + yearFilter?: number; + yearSort?: FilterSort; + } export interface OsocEdition extends KeyRequest { year: number; @@ -791,8 +1330,7 @@ export namespace Requests { export interface UpdateStudent extends IdRequest { emailOrGithub?: string; - firstName?: string; - lastName?: string; + name?: string; gender?: string; pronouns?: string; nickname?: string; @@ -808,11 +1346,14 @@ export namespace Requests { export interface Suggest extends IdRequest { suggestion: InternalTypes.Suggestion; + job_application_id: number; reason?: string; } export interface Confirm extends IdRequest { - reply?: InternalTypes.Suggestion; + reply: InternalTypes.Suggestion; + job_application_id: number; + reason?: string; } export interface UpdateLoginUser extends IdRequest { @@ -823,8 +1364,7 @@ export namespace Requests { } export interface UserRequest { - firstName: string; - lastName: string; + name: string; email: string; pass: string; } @@ -835,7 +1375,9 @@ export namespace Requests { partner: string; start: Date; end: Date; - positions: number; + roles: { roles: { name: string; positions: number }[] }; + description: string; + coaches: { coaches: number[] }; } export interface ModProject extends IdRequest { @@ -843,15 +1385,26 @@ export namespace Requests { partner?: string; start?: Date; end?: Date; - positions?: number; osocId?: number; + roles?: { roles: { name: string; positions: number }[] }; + description?: string; + addCoaches?: { coaches: number[] }; + removeCoaches?: { coaches: number[] }; } - export interface ProjectFilter extends KeyRequest {} + export interface ProjectFilter extends PaginableRequest { + projectNameFilter?: string; + clientNameFilter?: string; + fullyAssignedFilter?: boolean; + osocYear?: number; + projectNameSort?: FilterSort; + clientNameSort?: FilterSort; + } export interface Draft extends IdRequest { studentId: number; role: string; + jobApplicationId: number; } export interface Followup extends IdRequest { @@ -917,6 +1470,15 @@ export namespace Requests { export interface RmDraftStudent extends IdRequest { studentId: number; } + + export interface Coach extends IdRequest { + loginUserId: number; + } + + export interface UserYearPermissions extends IdRequest { + login_user_id: number; + osoc_id: number; + } } /** @@ -933,9 +1495,7 @@ export type Table = "project" | "student"; * A route callback is a function taking an Express js request and returning a * promise (resolving to an API response). */ -export type RouteCallback = ( - req: express.Request -) => Promise; +export type RouteCallback = (req: express.Request) => Promise; /** * Helper type for unsafe type checks. @@ -959,13 +1519,34 @@ export interface Email { */ export interface ServerToClientEvents { loginUserUpdated: () => void; + loginUserActivated: () => void; + loginUserDisabled: () => void; + registrationReceived: () => void; + studentSuggestionCreated: (studentId: number) => void; + studentWasDeleted: (studentId: number) => void; + projectWasCreatedOrDeleted: () => void; + projectWasModified: (projectId: number) => void; + osocWasCreatedOrDeleted: () => void; } /** * types for socket.io when sending something from the client to the server */ export interface ClientToServerEvents { - updateUser: (loginUserId: number) => void; + updateRoleUser: () => void; + activateUser: () => void; + disableUser: () => void; + submitRegistration: () => void; + studentSuggestionSent: (studentId: number) => void; + studentDecisionSent: (studentId: number) => void; + studentDelete: (studentId: number) => void; + projectCreated: () => void; + projectModified: (projectId: number) => void; + coachAssignedToProjectChange: (projectId: number) => void; + studentAssignedToProjectChange: (projectId: number) => void; + projectDeleted: () => void; + osocDeleted: () => void; + osocCreated: () => void; } /** @@ -987,3 +1568,18 @@ export enum Decision { MAYBE = "MAYBE", NO = "NO", } + +export enum AccountStatus { + ACTIVATED = "ACTIVATED", + PENDING = "PENDING", + DISABLED = "DISABLED", +} + +export enum EmailStatus { + APPLIED = "APPLIED", + APPROVED = "APPROVED", + AWAITING_PROJECT = "AWAITING_PROJECT", + CONTRACT_CONFIRMED = "CONTRACT_CONFIRMED", + CONTRACT_DECLINED = "CONTRACT_DECLINED", + REJECTED = "REJECTED", +} diff --git a/backend/utility.ts b/backend/utility.ts index ba163a85..11725757 100644 --- a/backend/utility.ts +++ b/backend/utility.ts @@ -14,12 +14,16 @@ import { Errors, InternalTypes, Requests, - Responses, RouteCallback, Table, Verb, WithUserID, } from "./types"; +import { getOsocYearsForLoginUser } from "./orm_functions/login_user"; +import { getAppliedYearsForStudent } from "./orm_functions/student"; +import IdRequest = Requests.IdRequest; +import { getProjectYear } from "./orm_functions/project"; +import { getOsocById } from "./orm_functions/osoc"; /** * The API error cooking functions. HTTP error codes are loaded from @@ -44,6 +48,12 @@ export const errors: Errors = { cookPendingAccount() { return config.apiErrors.pendingAccount; }, + cookWrongSuggestionYear() { + return config.apiErrors.studentSuggestion.insufficientRights; + }, + cookWrongOsocYear() { + return config.apiErrors.modifyProject.insufficientRights; + }, cookNonExistent(url: string) { return { @@ -99,18 +109,6 @@ export function getSessionKey(req: express.Request): string { return authHeader.replace(config.global.authScheme + " ", ""); } -/** - * Promise-based debugging function. Logs the data, then passes it through - * (using `Promise.resolve`). - * - * @param data The data to log and pass through. - * @returns A `Promise` resolving with the given data. - */ -export function debug(data: unknown): Promise { - console.log(data); - return Promise.resolve(data); -} - /** * Finishes a promise chain by sending a response. * @param resp The Express.js response. @@ -210,9 +208,9 @@ export function logRequest( * @param prom The promise with the data or error. * @returns An empty promise (`Promise`). */ -export async function respOrErrorNoReinject( +export async function respOrErrorNoReinject>( res: express.Response, - prom: Promise + prom: Promise ): Promise { const isError = (err: Anything): boolean => { return err != undefined && "http" in err && "reason" in err; @@ -220,15 +218,10 @@ export async function respOrErrorNoReinject( return prom .then((data) => { - console.log(data); return Promise.resolve(data); }) - .then( - (data: Responses.ApiResponse): Promise => - replySuccess(res, data as typeof data) - ) + .then((data): Promise => replySuccess(res, data as typeof data)) .catch((err: unknown): Promise => { - console.log(err); if (isError(err as Anything)) return replyError(res, err as ApiError); console.log("UNCAUGHT ERROR " + JSON.stringify(err)); @@ -248,10 +241,10 @@ export async function respOrErrorNoReinject( * that's Keyed). * @returns An empty promise (`Promise`). */ -export async function respOrError( +export async function respOrError>( req: express.Request, res: express.Response, - prom: Promise + prom: Promise ): Promise { return respOrErrorNoReinject( res, @@ -360,6 +353,69 @@ export async function isAdmin( ); } +/** + * returns the userData in a promise if the loginUser should be able to see the requested student + * Otherwise it returns a rejection with insufficient rights. + * + * @param userData: object that contains the studentId whose data is queried and the id of the loginUser that is querying the data + */ +export async function checkYearPermissionStudent( + userData: WithUserID +): Promise> { + // get the years that are visible for the loginUser + const visibleYears = await getOsocYearsForLoginUser(userData.userId); + // get the years that the student applied in + const studentAppliedYears = await getAppliedYearsForStudent( + userData.data.id + ); + + // check if the student has a job application that is inside the visible years + if (studentAppliedYears.some((year) => visibleYears.indexOf(year) >= 0)) { + return userData; + } + return Promise.reject(errors.cookInsufficientRights()); +} + +/** + * returns the userData object if the user is allowed to see the project + * Otherwise it returns an insufficient rights error. + * @param userData: object with the userId and projectId + */ +export async function checkYearPermissionProject( + userData: WithUserID +): Promise> { + // get the years that are visible for the loginUser + const visibleYears = await getOsocYearsForLoginUser(userData.userId); + // get the year that the project belongs to + const projectYear = await getProjectYear(userData.data.id); + + // check if the project year is inside the visible years for the user + if (visibleYears.includes(projectYear)) { + return userData; + } + return Promise.reject(errors.cookInsufficientRights()); +} + +/** + * returns the userData object if the user is allowed to see the osoc edition + * Otherwise it returns an insufficient rights error. + * @param userData: object with the userId and osocID + */ +export async function checkYearPermissionOsoc( + userData: WithUserID +): Promise> { + // get the years that are visible for the loginUser + const visibleYears = await getOsocYearsForLoginUser(userData.userId); + // get the year that the project belongs to + const osoc = await getOsocById(userData.data.id); + + // check if the project year is inside the visible years for the user + if (osoc !== null && visibleYears.includes(osoc.year)) { + return userData; + } + return Promise.reject(errors.cookInsufficientRights()); +} + /** * Generates a new session key. * @returns The newly generated session key. @@ -415,7 +471,7 @@ export async function refreshAndInjectKey( * @param path The (relative) route path. * @param callback The function which will respond. */ -export function route( +export function route>( router: express.Router, verb: Verb, path: string, @@ -426,35 +482,6 @@ export function route( ); } -/** - * Contains all boilerplate to install a route with a path and HTTP verb for a - * route that returns only an updated session key. - * @param router The router to install to. - * @param verb The HTTP verb. - * @param path The (relative) route path. - * @param callback The function which will respond. - * @deprecated Use route instead. - */ -export function routeKeyOnly( - router: express.Router, - verb: Verb, - path: string, - callback: RouteCallback -): void { - console.log("[WARNING]: routeKeyOnly is deprecated. Use route instead."); - console.log("Stack trace:"); - console.log("------------"); - console.log(new Error().stack); - router[verb](path, (req: express.Request, res: express.Response) => - respOrErrorNoReinject( - res, - callback(req) - .then((toupd) => refreshKey(toupd.sessionkey)) - .then(() => Promise.resolve({})) - ) - ); -} - /** * Checks whether the object contains a valid ID. */ diff --git a/backend/websocket_events/login_user.ts b/backend/websocket_events/login_user.ts index ce0f06a8..c4bc40f3 100644 --- a/backend/websocket_events/login_user.ts +++ b/backend/websocket_events/login_user.ts @@ -5,7 +5,7 @@ import { ServerToClientEvents, SocketData, } from "../types"; - +/* istanbul ignore file */ // don't test this file because there is no real logic. Only the setup of listeners. /** * function to register the listeners to the sockets. * This function is used/imported in the index.ts file @@ -26,9 +26,20 @@ export function registerLoginUserHandlers( SocketData > ) { - const loginUserUpdated = (loginUserId: number) => { + const loginUserRoleUpdated = () => { socket.broadcast.emit("loginUserUpdated"); - console.log("updated user:" + loginUserId); }; - socket.on("updateUser", loginUserUpdated); + const loginUserActivated = () => { + socket.broadcast.emit("loginUserActivated"); + }; + const loginUserDisabled = () => { + socket.broadcast.emit("loginUserDisabled"); + }; + const newRegister = () => { + socket.broadcast.emit("registrationReceived"); + }; + socket.on("updateRoleUser", loginUserRoleUpdated); + socket.on("activateUser", loginUserActivated); + socket.on("disableUser", loginUserDisabled); + socket.on("submitRegistration", newRegister); } diff --git a/backend/websocket_events/osoc.ts b/backend/websocket_events/osoc.ts new file mode 100644 index 00000000..88d5223c --- /dev/null +++ b/backend/websocket_events/osoc.ts @@ -0,0 +1,35 @@ +import { Server, Socket } from "socket.io"; +import { + ClientToServerEvents, + InterServerEvents, + ServerToClientEvents, + SocketData, +} from "../types"; +/* istanbul ignore file */ // don't test this file because there is no real logic. Only the setup of listeners. +/** + * function to register the listeners to the sockets. + * This function is used/imported in the index.ts file + * @param io: the io/server instance from socket.io + * @param socket: the socket instance from the server + */ +export function registerOsocHandlers( + io: Server< + ClientToServerEvents, + ServerToClientEvents, + InterServerEvents, + SocketData + >, + socket: Socket< + ClientToServerEvents, + ServerToClientEvents, + InterServerEvents, + SocketData + > +) { + const OsocCreatedOrDeleted = () => { + socket.broadcast.emit("osocWasCreatedOrDeleted"); + }; + + socket.on("osocDeleted", OsocCreatedOrDeleted); + socket.on("osocCreated", OsocCreatedOrDeleted); +} diff --git a/backend/websocket_events/project.ts b/backend/websocket_events/project.ts new file mode 100644 index 00000000..af3be655 --- /dev/null +++ b/backend/websocket_events/project.ts @@ -0,0 +1,41 @@ +import { Server, Socket } from "socket.io"; +import { + ClientToServerEvents, + InterServerEvents, + ServerToClientEvents, + SocketData, +} from "../types"; +/* istanbul ignore file */ // don't test this file because there is no real logic. Only the setup of listeners. +/** + * function to register the listeners to the sockets. + * This function is used/imported in the index.ts file + * @param io: the io/server instance from socket.io + * @param socket: the socket instance from the server + */ +export function registerProjectHandlers( + io: Server< + ClientToServerEvents, + ServerToClientEvents, + InterServerEvents, + SocketData + >, + socket: Socket< + ClientToServerEvents, + ServerToClientEvents, + InterServerEvents, + SocketData + > +) { + const projectCreatedOrDeleted = () => { + socket.broadcast.emit("projectWasCreatedOrDeleted"); + }; + const projectModified = (projectId: number) => { + socket.broadcast.emit("projectWasModified", projectId); + }; + + socket.on("projectCreated", projectCreatedOrDeleted); + socket.on("projectModified", projectModified); + socket.on("coachAssignedToProjectChange", projectModified); + socket.on("studentAssignedToProjectChange", projectModified); + socket.on("projectDeleted", projectCreatedOrDeleted); +} diff --git a/backend/websocket_events/student.ts b/backend/websocket_events/student.ts new file mode 100644 index 00000000..4e0eed53 --- /dev/null +++ b/backend/websocket_events/student.ts @@ -0,0 +1,40 @@ +import { Server, Socket } from "socket.io"; +import { + ClientToServerEvents, + InterServerEvents, + ServerToClientEvents, + SocketData, +} from "../types"; +/* istanbul ignore file */ + +/** + * function to register the listeners to the sockets. + * This function is used/imported in the index.ts file + * @param io: the io/server instance from socket.io + * @param socket: the socket instance from the server + */ +export function registerStudentHandlers( + io: Server< + ClientToServerEvents, + ServerToClientEvents, + InterServerEvents, + SocketData + >, + socket: Socket< + ClientToServerEvents, + ServerToClientEvents, + InterServerEvents, + SocketData + > +) { + const studentSuggestionCreated = (studentId: number) => { + socket.broadcast.emit("studentSuggestionCreated", studentId); + }; + const studentDeleted = (studentId: number) => { + socket.broadcast.emit("studentWasDeleted", studentId); + }; + + socket.on("studentSuggestionSent", studentSuggestionCreated); + socket.on("studentDecisionSent", studentSuggestionCreated); + socket.on("studentDelete", studentDeleted); +} diff --git a/database/Dockerfile b/database/Dockerfile index 4363663f..fc9661b2 100644 --- a/database/Dockerfile +++ b/database/Dockerfile @@ -1,4 +1,4 @@ -FROM postgres:14.2 +FROM postgres:14.3 RUN apt-get update && apt-get -y install git build-essential postgresql-server-dev-14 diff --git a/database/startupScripts/create_db.sql b/database/startupScripts/create_db.sql index e1ca1614..d5ab714a 100644 --- a/database/startupScripts/create_db.sql +++ b/database/startupScripts/create_db.sql @@ -2,8 +2,7 @@ CREATE TABLE IF NOT EXISTS person( person_id SERIAL PRIMARY KEY, email VARCHAR(320) UNIQUE, /* max email length is 320 characters */ github TEXT UNIQUE, - firstname TEXT NOT NULL, - lastname TEXT NOT NULL, + "name" TEXT NOT NULL, github_id TEXT UNIQUE, CONSTRAINT login CHECK (email IS NOT NULL OR (github IS NOT NULL AND github_id IS NOT NULL)), CONSTRAINT email_check CHECK (email is NULL or email LIKE '%_@__%.__%') @@ -46,7 +45,7 @@ CREATE TYPE account_status_enum as ENUM ('ACTIVATED', 'PENDING', 'DISABLED'); CREATE TABLE IF NOT EXISTS login_user( login_user_id SERIAL PRIMARY KEY, person_id SERIAL NOT NULL UNIQUE REFERENCES person(person_id), - "password" TEXT NULL, + "password" VARCHAR(60) NULL, is_admin BOOLEAN NOT NULL, is_coach BOOLEAN NOT NULL, account_status account_status_enum NOT NULL, @@ -78,11 +77,11 @@ CREATE TABLE IF NOT EXISTS osoc( /* enum used in job appliction for the email status */ -CREATE TYPE email_status_enum AS ENUM ('SCHEDULED', 'SENT', 'FAILED', 'NONE', 'DRAFT'); +CREATE TYPE email_status_enum AS ENUM ('APPLIED', 'AWAITING PROJECT', 'APPROVED', 'CONTRACT CONFIRMED', 'CONTRACT DECLINED', 'REJECTED'); CREATE TABLE IF NOT EXISTS job_application ( job_application_id SERIAL PRIMARY KEY, - student_id SERIAL NOT NULL REFERENCES student(student_id), + student_id INT REFERENCES student(student_id) ON DELETE SET NULL, student_volunteer_info TEXT NOT NULL, responsibilities TEXT, fun_fact TEXT NOT NULL, @@ -103,7 +102,7 @@ CREATE TYPE decision_enum AS ENUM ('YES', 'NO', 'MAYBE'); CREATE TABLE IF NOT EXISTS evaluation ( evaluation_id SERIAL PRIMARY KEY, - login_user_id SERIAL NOT NULL REFERENCES login_user(login_user_id), + login_user_id INT REFERENCES login_user(login_user_id) ON DELETE SET NULL, job_application_id SERIAL NOT NULL REFERENCES job_application(job_application_id), decision decision_enum NOT NULL, motivation TEXT, @@ -125,9 +124,7 @@ CREATE TABLE IF NOT EXISTS project ( description TEXT, start_date DATE NOT NULL, end_date DATE NOT NULL, - positions SMALLINT NOT NULL, - CONSTRAINT dates CHECK (start_date <= end_date), - CONSTRAINT valid_positions CHECK (positions > 0) + CONSTRAINT dates CHECK (start_date <= end_date) ); @@ -151,11 +148,11 @@ CREATE TABLE IF NOT EXISTS project_role ( CREATE TYPE contract_status_enum AS ENUM ('DRAFT', 'APPROVED', 'CANCELLED', 'WAIT_APPROVAL', 'SIGNED', 'SENT'); CREATE TABLE IF NOT EXISTS contract( - contract_id SERIAL PRIMARY KEY, - student_id SERIAL NOT NULL REFERENCES student (student_id), - project_role_id SERIAL NOT NULL REFERENCES project_role (project_role_id), + contract_id SERIAL PRIMARY KEY, + student_id INT REFERENCES student (student_id) ON DELETE SET NULL, + project_role_id INT REFERENCES project_role (project_role_id) ON DELETE SET NULL, information TEXT, - created_by_login_user_id SERIAL NOT NULL REFERENCES login_user (login_user_id), + created_by_login_user_id INT REFERENCES login_user (login_user_id) ON DELETE SET NULL, contract_status contract_status_enum NOT NULL ); @@ -196,7 +193,7 @@ CREATE TABLE IF NOT EXISTS attachment( CREATE TABLE IF NOT EXISTS template_email( template_email_id SERIAL PRIMARY KEY, - owner_id SERIAL NOT NULL REFERENCES login_user(login_user_id), + owner_id INT REFERENCES login_user(login_user_id) ON DELETE SET NULL, name TEXT NOT NULL, content TEXT NOT NULL, subject TEXT, @@ -204,6 +201,13 @@ CREATE TABLE IF NOT EXISTS template_email( UNIQUE(owner_id, name) ); +CREATE TABLE IF NOT EXISTS login_user_osoc( + login_user_osoc_id SERIAL PRIMARY KEY, + login_user_id INT NOT NULL REFERENCES login_user(login_user_id), + osoc_id INT NOT NULL REFERENCES osoc(osoc_id), + unique(login_user_id, osoc_id) +); + /* Create database extension for job scheduler pg_cron */ CREATE EXTENSION pg_cron; diff --git a/database/startupScripts/generate_data.sql b/database/startupScripts/generate_data.sql index fb3293f1..9cf40de7 100644 --- a/database/startupScripts/generate_data.sql +++ b/database/startupScripts/generate_data.sql @@ -1,19 +1,19 @@ /* Insert data into person table */ -INSERT INTO person(email, firstname, lastname) -VALUES('alicestudent@gmail.com', 'Alice', 'Smith'), -('bob.admin@osoc.com', 'Bob', 'Jones'), ('Trudy@coach@gmail.com', 'Trudy', 'Taylor'), -('osoc2@mail.com', 'Osoc', 'TeamTwo'); +INSERT INTO person(email, "name") +VALUES('alicestudent@gmail.com', 'Alice Smith'), +('bob.admin@osoc.com', 'Bob Jones'), ('Trudycoach@gmail.com', 'Trudy Taylor'), +('osoc2@mail.com', 'Osoc TeamTwo'); /* Insert data into student table */ INSERT INTO student(person_id, gender, phone_number, nickname, alumni) -VALUES((SELECT person_id FROM person WHERE firstname = 'Alice'), +VALUES((SELECT person_id FROM person WHERE "name" LIKE 'Alice%'), 'Female', '0032476553498', 'Unicorn', TRUE); /* Insert data into login_user table */ INSERT INTO login_user(person_id, password, is_admin, is_coach, account_status) -VALUES((SELECT person_id FROM person WHERE firstname = 'Bob'), 'Bob4life', TRUE, FALSE , 'ACTIVATED'), -((SELECT person_id FROM person WHERE firstname = 'Trudy'), 'TrudyRulesAll777', FALSE, TRUE, 'PENDING'), -((SELECT person_id FROM person WHERE email = 'osoc2@mail.com'), '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', TRUE, FALSE, 'ACTIVATED'); +VALUES((SELECT person_id FROM person WHERE "name" LIKE 'Bob%'), '$2b$08$ffQO2UCEFHUHcn9d.XHHg.hFKn7oF5AOW82J.hsOqq8gV0TzMEuzq', TRUE, FALSE , 'ACTIVATED'), +((SELECT person_id FROM person WHERE "name" LIKE 'Trudy%'), '$2b$08$XDDmyKZnWsai9wVAW7r.GOOv7pGKa7oHLlBhVAqTmPgiscMzynpVq', FALSE, TRUE, 'PENDING'), +((SELECT person_id FROM person WHERE email = 'osoc2@mail.com'), '$2b$08$MCblaKGOOBV7NpiW62GEc.km732o6XWDJxU6SfU3NMENxMuCWFlJq', TRUE, FALSE, 'ACTIVATED'); /* Insert data into osoc table */ INSERT INTO osoc(year)VALUES(2022); @@ -23,7 +23,7 @@ INSERT INTO job_application(student_id, osoc_id, student_volunteer_info, respons edus, edu_level, edu_duration, edu_year, edu_institute, email_status, created_at)VALUES ((SELECT student_id FROM student WHERE phone_number = '0032476553498'), (SELECT osoc_id FROM osoc WHERE year = 2022), 'Yes, I can work with a student employment agreement in Belgium', 'Very responsible', 'I am a very funny fact', TRUE, '{"Informatics"}', - 'Universitarian', 3, '2022', 'Ghent University', 'NONE', '2022-03-14 23:10:00+01'); + 'Universitarian', 3, '2022', 'Ghent University', 'APPLIED', '2022-03-14 23:10:00+01'); /* Insert data into evaluation table */ INSERT INTO evaluation(login_user_id, job_application_id, decision, motivation, is_final)VALUES @@ -34,8 +34,8 @@ INSERT INTO job_application(student_id, osoc_id, student_volunteer_info, respons INSERT INTO role(name)VALUES('Developer'); /* Insert data into project table */ - INSERT INTO project(name, osoc_id, partner, start_date, end_date, positions)VALUES('OSOC Platform', - (SELECT osoc_id FROM osoc WHERE year = 2022), 'UGent', DATE '2022-07-01', DATE '2022-08-15', 2); + INSERT INTO project(name, osoc_id, partner, start_date, end_date)VALUES('OSOC Platform', + (SELECT osoc_id FROM osoc WHERE year = 2022), 'UGent', DATE '2022-07-01', DATE '2022-08-15'); /* Insert data into project_user table */ INSERT INTO project_user(login_user_id, project_id)VALUES((SELECT login_user_id FROM login_user WHERE is_admin = TRUE AND person_id = 2), @@ -73,6 +73,10 @@ INSERT INTO attachment(job_application_id, data, type)VALUES ((SELECT job_application_id from job_application WHERE fun_fact = 'I am a very funny fact'), '{I really need the money}', '{MOTIVATION_STRING}'); +/* Insert into the login_user_osoc table */ +INSERT INTO login_user_osoc(login_user_id, osoc_id) VALUES ((SELECT login_user_id FROM login_user WHERE is_admin = TRUE AND person_id = 4), +(SELECT osoc_id FROM osoc WHERE year = 2022)); + /* Insert data into template table */ INSERT INTO template_email(owner_id, name, content)VALUES ((SELECT login_user_id FROM login_user WHERE is_admin = TRUE AND person_id = 2), 'Some Template', '

    I am a template

    '); diff --git a/docs/API/api.json b/docs/API/api.json index a18a5a86..6ee6d29f 100644 --- a/docs/API/api.json +++ b/docs/API/api.json @@ -310,7 +310,7 @@ "data": { "type": "array", "items": { - "$ref": "#/components/schemas/LoginUser" + "$ref": "#/components/schemas/CoachUser" } } } @@ -468,153 +468,18 @@ } } }, - "/coach/request": { - "get": { - "tags": [ - "coach" - ], - "description": "Lists all coach requests.", - "operationId": "all_coach_requests", - "parameters": [ - { - "name": "sessionkey", - "in": "header", - "description": "Your current session key.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "The data list contains info of all coach requests.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "activated": { - "type": "string" - }, - "admin": { - "type": "boolean" - }, - "coach": { - "type": "boolean" - }, - "person_data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "name": { - "type": "string" - } - } - } - } - } - } - } - } - } - } - }, - "400": { - "description": "One of the arguments is incorrect or not present." - }, - "401": { - "description": "The user has to log in first." - }, - "403": { - "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." - }, - "423": { - "description": "Your account was deactivated. Please contact the webmaster." - }, - "424": { - "description": "Your account hasn't been activated yet. Please try again later." - } - } - } - }, - "/followup/all": { + "/followup/": { "get": { "tags": [ "followup" ], - "description": "Returns a list of all the followups in the system.", - "operationId": "all_followups", - "parameters": [ - { - "name": "sessionkey", - "in": "header", - "description": "Your current session key.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "The data list contains info of all followups in the system.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Followup" - } - } - } - } - } - } - }, - "400": { - "description": "One of the arguments is incorrect or not present." - }, - "401": { - "description": "The user has to log in first." - }, - "403": { - "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." - }, - "412": { - "description": "The data you requested does not exist (yet)." - }, - "423": { - "description": "Your account was deactivated. Please contact the webmaster." - }, - "424": { - "description": "Your account hasn't been activated yet. Please try again later." - } - } - } - }, - "/followup/": { - "get": { - "tags": [ - "followup" - ], - "description": "Lists all details about the followup with the given id.", + "description": "Lists all details about the followup matching the job application with the given id.", "operationId": "followup_id_get", "parameters": [ { "name": "id", "in": "header", - "description": "The id of the followup.", + "description": "The id of the job application.", "required": true, "schema": { "type": "number" @@ -665,13 +530,13 @@ "tags": [ "followup" ], - "description": "Attempts to update a followup with the given id and type.", + "description": "Attempts to update a followup matching the job application with the given id and type.", "operationId": "followup_id_post", "parameters": [ { "name": "id", "in": "header", - "description": "The id of the followup.", + "description": "The id of the job application.", "required": true, "schema": { "type": "number" @@ -694,11 +559,12 @@ "schema": { "type": "string", "enum": [ - "DRAFT", - "FAILED", - "NONE", - "SCHEDULED", - "SENT" + "APPLIED", + "AWAITING_PROJECT", + "APPROVED", + "CONTRACT_CONFIRMED", + "CONTRACT_DECLINED", + "REJECTED" ] } } @@ -853,7 +719,7 @@ { "name": "password", "in": "header", - "description": "The hashed password of the user to log in.", + "description": "The password of the user to log in.", "required": true, "schema": { "type": "string" @@ -976,15 +842,15 @@ } } }, - "204": { - "description": "This endpoint requires an ID. The ID you provided was invalid." - }, "400": { "description": "One of the arguments is incorrect or not present." }, "401": { "description": "The user has to log in first." }, + "403": { + "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." + }, "423": { "description": "Your account was deactivated. Please contact the webmaster." }, @@ -1110,15 +976,15 @@ } } } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" } } } } } }, - "204": { - "description": "This endpoint requires an ID. The ID you provided was invalid." - }, "401": { "description": "The user has to log in first." }, @@ -1163,14 +1029,7 @@ ], "responses": { "200": { - "description": "The specified osoc edition was removed. The response is an empty object.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } + "description": "The specified osoc edition was removed. The response is an empty object." }, "204": { "description": "This endpoint requires an ID. The ID you provided was invalid." @@ -1214,7 +1073,16 @@ "operationId": "create_project", "parameters": [ { - "name": "end_date", + "name": "sessionkey", + "in": "header", + "description": "Your current session key.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "end", "in": "header", "description": "The end date of this project.", "required": true, @@ -1250,22 +1118,59 @@ } }, { - "name": "positions", + "name": "coaches", "in": "header", - "description": "The amount of positions for the project.", + "description": "The coaches for this project.", "required": true, "schema": { - "type": "number" + "type": "array", + "items": { + "type": "number" + } + } + }, + { + "name": "roles", + "in": "header", + "description": "The roles for the project.", + "required": true, + "schema": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "positions": { + "type": "number" + } + } + } + } + } } }, { - "name": "start_date", + "name": "start", "in": "header", "description": "The start date of this project.", "required": true, "schema": { "type": "string" } + }, + { + "name": "description", + "in": "header", + "description": "The description of this project.", + "required": true, + "schema": { + "type": "string" + } } ], "responses": { @@ -1288,6 +1193,9 @@ "403": { "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." }, + "412": { + "description": "The data you requested does not exist (yet)." + }, "423": { "description": "Your account was deactivated. Please contact the webmaster." }, @@ -1335,6 +1243,9 @@ "403": { "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." }, + "412": { + "description": "The data you requested does not exist (yet)." + }, "423": { "description": "Your account was deactivated. Please contact the webmaster." }, @@ -1394,6 +1305,9 @@ "403": { "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." }, + "412": { + "description": "The data you requested does not exist (yet)." + }, "423": { "description": "Your account was deactivated. Please contact the webmaster." }, @@ -1435,6 +1349,30 @@ "type": "string" } }, + { + "name": "roles", + "in": "header", + "description": "The roles to modify.", + "schema": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "positions": { + "type": "number" + } + } + } + } + } + } + }, { "name": "name", "in": "header", @@ -1466,6 +1404,38 @@ "schema": { "type": "string" } + }, + { + "name": "addCoaches", + "in": "header", + "description": "The ID's of the coaches to add to this project.", + "schema": { + "type": "object", + "properties": { + "coaches": { + "type": "array", + "items": { + "type": "number" + } + } + } + } + }, + { + "name": "removeCoaches", + "in": "header", + "description": "The ID's of the coaches to remove from this project.", + "schema": { + "type": "object", + "properties": { + "coaches": { + "type": "array", + "items": { + "type": "number" + } + } + } + } } ], "responses": { @@ -1491,6 +1461,9 @@ "403": { "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." }, + "412": { + "description": "The data you requested does not exist (yet)." + }, "423": { "description": "Your account was deactivated. Please contact the webmaster." }, @@ -1550,144 +1523,13 @@ } } }, - "/project//draft": { - "get": { + "/project//assignee": { + "delete": { "tags": [ "project" ], - "description": "Lists all drafted students of the selected project.", - "operationId": "all_students_project", - "parameters": [ - { - "name": "id", - "in": "header", - "description": "The id of the project.", - "required": true, - "schema": { - "type": "number" - } - }, - { - "name": "sessionkey", - "in": "header", - "description": "Your current session key.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "The students list contains info about all drafted students of this project.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Drafted_students_project" - } - } - } - }, - "400": { - "description": "One of the arguments is incorrect or not present." - }, - "401": { - "description": "The user has to log in first." - }, - "423": { - "description": "Your account was deactivated. Please contact the webmaster." - }, - "424": { - "description": "Your account hasn't been activated yet. Please try again later." - } - } - }, - "post": { - "tags": [ - "project" - ], - "description": "Add the student to the selected project.", - "operationId": "add_student_to_project", - "parameters": [ - { - "name": "id", - "in": "header", - "description": "The id of the project.", - "required": true, - "schema": { - "type": "number" - } - }, - { - "name": "role", - "in": "header", - "description": "The selected role for this student.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "sessionkey", - "in": "header", - "description": "Your current session key.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "studentId", - "in": "header", - "description": "The id of the selected student.", - "required": true, - "schema": { - "type": "number" - } - } - ], - "responses": { - "200": { - "description": "The data object contains the role of the student if the student contributes to the project.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Draft_student_project" - } - } - } - }, - "204": { - "description": "The selected student is not assigned to this project." - }, - "400": { - "description": "One of the arguments is incorrect or not present." - }, - "401": { - "description": "The user has to log in first." - }, - "403": { - "description": "Unauthorized request. You do not have sufficient rights to access this endpoint." - }, - "409": { - "description": "That role doesn't exist." - }, - "423": { - "description": "Your account was deactivated. Please contact the webmaster." - }, - "424": { - "description": "Your account hasn't been activated yet. Please try again later." - } - } - } - }, - "/project//assignee": { - "delete": { - "tags": [ - "project" - ], - "description": "Removes the student from the project.", - "operationId": "project_student_delete", + "description": "Removes the student from the project.", + "operationId": "project_student_delete", "parameters": [ { "name": "id", @@ -1736,53 +1578,6 @@ } } }, - "/project/conflicts": { - "get": { - "tags": [ - "project" - ], - "description": "Returns a list of all project conflicts.", - "operationId": "project_conflicts", - "parameters": [ - { - "name": "sessionkey", - "in": "header", - "description": "Your current session key.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "The data list contains the conflicting projects for the student with id 'student'.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Project_conflicts" - } - } - } - }, - "400": { - "description": "One of the arguments is incorrect or not present." - }, - "401": { - "description": "The user has to log in first." - }, - "412": { - "description": "The data you requested does not exist (yet)." - }, - "423": { - "description": "Your account was deactivated. Please contact the webmaster." - }, - "424": { - "description": "Your account hasn't been activated yet. Please try again later." - } - } - } - }, "/reset": { "post": { "tags": [ @@ -1869,7 +1664,7 @@ ], "responses": { "200": { - "description": "Updated sessionkey as hex string E.g. \"A1BEF4\".", + "description": "A new session key.", "content": { "application/json": { "schema": { @@ -2253,6 +2048,15 @@ "type": "string" } }, + { + "name": "job_application_id", + "in": "header", + "description": "The id of the student's job application.", + "required": true, + "schema": { + "type": "number" + } + }, { "name": "suggestion", "in": "header", @@ -2274,40 +2078,7 @@ ], "responses": { "200": { - "description": "This contains info about a suggestion.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "decision": { - "type": "string", - "enum": [ - "YES", - "MAYBE", - "NO" - ] - }, - "evaluation_id": { - "type": "number" - }, - "isFinal": { - "type": "boolean" - }, - "reason": { - "type": "string", - "nullable": true - }, - "senderFirstname": { - "type": "string" - }, - "senderLastname": { - "type": "string" - } - } - } - } - } + "description": "This contains info about a suggestion. The response is an empty object" }, "204": { "description": "This endpoint requires an ID. The ID you provided was invalid." @@ -2341,7 +2112,7 @@ "description": "The id of the student.", "required": true, "schema": { - "type": "string" + "type": "number" } }, { @@ -2353,6 +2124,15 @@ "type": "string" } }, + { + "name": "job_application_id", + "in": "header", + "description": "The id of the student's job application.", + "required": true, + "schema": { + "type": "number" + } + }, { "name": "reason", "in": "header", @@ -2401,26 +2181,27 @@ "operationId": "filter_students", "parameters": [ { - "name": "sessionkey", + "name": "osocYear", "in": "header", - "description": "Your current session key.", + "description": "The year of the osoc edition.", "required": true, "schema": { - "type": "string" + "type": "number" } }, { - "name": "alumniFilter", + "name": "sessionkey", "in": "header", - "description": "The alumni filter.", + "description": "Your current session key.", + "required": true, "schema": { - "type": "boolean" + "type": "string" } }, { - "name": "alumniSort", + "name": "alumniFilter", "in": "header", - "description": "Sorting by alumni (asc or desc).", + "description": "The alumni filter.", "schema": { "type": "string" } @@ -2430,7 +2211,7 @@ "in": "header", "description": "The student-coach filter.", "schema": { - "type": "boolean" + "type": "string" } }, { @@ -2449,6 +2230,21 @@ "type": "string" } }, + { + "name": "emailStatusFilter", + "in": "header", + "description": "The email status filter.", + "schema": { + "type": "string", + "enum": [ + "DRAFT", + "FAILED", + "NONE", + "SCHEDULED", + "SENT" + ] + } + }, { "name": "firstNameFilter", "in": "header", @@ -2494,14 +2290,6 @@ } } }, - { - "name": "roleSort", - "in": "header", - "description": "Sorting by role (asc or desc).", - "schema": { - "type": "string" - } - }, { "name": "statusFilter", "in": "header", @@ -2510,8 +2298,8 @@ "type": "string", "enum": [ "MAYBE", - "FALSE", - "TRUE" + "NO", + "YES" ] } } @@ -2939,6 +2727,9 @@ "items": { "$ref": "#/components/schemas/LoginUser" } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" } } } @@ -3204,68 +2995,7 @@ "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "login_user": { - "type": "object", - "properties": { - "account_status": { - "type": "string", - "enum": [ - "ACTIVATED", - "DISABLED", - "PENDING" - ] - }, - "is_admin": { - "type": "boolean" - }, - "is_coach": { - "type": "boolean" - }, - "login_user_id": { - "type": "number" - }, - "password": { - "type": "string" - }, - "person": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "firstname": { - "type": "string" - }, - "github": { - "type": "string" - }, - "github_id": { - "type": "string" - }, - "lastname": { - "type": "string" - }, - "person_id": { - "type": "number" - } - } - }, - "person_id": { - "type": "number" - } - } - } - } - }, - "sessionkey": { - "type": "string" - } - } + "$ref": "#/components/schemas/LoginUser" } } } @@ -3332,7 +3062,7 @@ ], "responses": { "200": { - "description": "The user associated with the session key has been modified. The response is an empty object.", + "description": "The user associated with the session key has been modified. The response contains either the old session key, or a new one if the password has been changed.", "content": { "application/json": { "schema": { @@ -3408,7 +3138,7 @@ "description": "True if the users are admins, else false.", "required": false, "schema": { - "type": "boolean" + "type": "string" } }, { @@ -3417,7 +3147,7 @@ "description": "True if the users are coaches, else false.", "required": false, "schema": { - "type": "boolean" + "type": "string" } }, { @@ -3464,6 +3194,9 @@ "items": { "$ref": "#/components/schemas/LoginUser" } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" } } } @@ -3548,9 +3281,51 @@ "LoginUser": { "type": "object", "properties": { - "activated": { - "type": "string", - "enum": [ + "login_user_id": { + "type": "number" + }, + "account_status": { + "type": "string", + "enum": [ + "ACTIVATED", + "DISABLED", + "PENDING" + ] + }, + "is_admin": { + "type": "boolean" + }, + "is_coach": { + "type": "boolean" + }, + "person": { + "type": "object", + "properties": { + "person_id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "github": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + }, + "xml": { + "name": "LoginUser" + } + }, + "CoachUser": { + "type": "object", + "properties": { + "activated": { + "type": "string", + "enum": [ "ACTIVATED", "DISABLED", "PENDING" @@ -3562,6 +3337,9 @@ "coach": { "type": "boolean" }, + "login_user_id": { + "type": "number" + }, "person_data": { "type": "object", "properties": { @@ -3635,11 +3413,12 @@ "status": { "type": "string", "enum": [ - "DRAFT", - "FAILED", - "NONE", - "SCHEDULED", - "SENT" + "APPLIED", + "AWAITING_PROJECT", + "APPROVED", + "CONTRACT_CONFIRMED", + "CONTRACT_DECLINED", + "REJECTED" ] }, "student": { @@ -3668,8 +3447,19 @@ "partner": { "type": "string" }, - "positions": { - "type": "number" + "roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "positions": { + "type": "number" + } + } + } }, "start_date": { "type": "string" @@ -3682,6 +3472,9 @@ "Project_coach": { "type": "object", "properties": { + "project_user_id": { + "type": "number" + }, "login_user": { "type": "object", "properties": { @@ -3704,54 +3497,6 @@ "name": "Project_coach" } }, - "Project_students": { - "type": "array", - "xml": { - "name": "Project_students" - }, - "items": { - "type": "object", - "properties": { - "contract_id": { - "type": "number" - }, - "contract_status": { - "type": "string", - "enum": [ - "APPROVED", - "CANCELLED", - "DRAFT", - "SENT", - "SIGNED", - "WAIT_APPROVAL" - ] - }, - "project_role": { - "type": "object", - "properties": { - "positions": { - "type": "number" - }, - "project_id": { - "type": "number" - }, - "project_role_id": { - "type": "number" - }, - "role_id": { - "type": "number" - } - } - }, - "student": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Student" - } - } - } - } - }, "Project_coaches": { "type": "array", "items": { @@ -3779,14 +3524,116 @@ "partner": { "type": "string" }, - "positions": { - "type": "number" + "description": { + "type": "string", + "nullable": true + }, + "roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "positions": { + "type": "number" + } + } + } }, "start_date": { "type": "string" }, - "students": { - "$ref": "#/components/schemas/Project_students" + "contracts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "student": { + "type": "object", + "properties": { + "student_id": { + "type": "number" + }, + "person": { + "$ref": "#/components/schemas/PersonAndID" + }, + "alumni": { + "type": "boolean" + }, + "nickname": { + "type": "string" + }, + "gender": { + "type": "string" + }, + "pronouns": { + "type": "string" + }, + "phone_number": { + "type": "string" + } + } + }, + "project_role": { + "type": "object", + "properties": { + "positions": { + "type": "number" + }, + "project_id": { + "type": "number" + }, + "project_role_id": { + "type": "number" + }, + "role_id": { + "type": "number" + }, + "role": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } + }, + "contract_id": { + "type": "number" + }, + "contract_status": { + "type": "string", + "enum": [ + "DRAFT", + "APPROVED", + "CANCELLED", + "WAIT_APPROVAL", + "SIGNED", + "SENT" + ] + }, + "login_user": { + "type": "object", + "properties": { + "login_user_id": { + "type": "number" + }, + "is_admin": { + "type": "boolean" + }, + "is_coach": { + "type": "boolean" + }, + "person": { + "$ref": "#/components/schemas/PersonAndID" + } + } + } + } + } } }, "xml": { @@ -3807,6 +3654,9 @@ "properties": { "data": { "$ref": "#/components/schemas/Project_list" + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" } }, "xml": { @@ -3831,141 +3681,324 @@ "end_date": { "type": "string" }, - "positions": { - "type": "number" + "description": { + "type": "string" }, "osoc_id": { "type": "number" + }, + "roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "positions": { + "type": "number" + } + } + } + }, + "coaches": { + "type": "array", + "items": { + "type": "object", + "properties": { + "project_user_id": { + "type": "number" + }, + "login_user": { + "type": "object", + "properties": { + "person": { + "$ref": "#/components/schemas/Person" + }, + "is_coach": { + "type": "boolean" + }, + "is_admin": { + "type": "boolean" + }, + "login_user_id": { + "type": "number" + } + } + } + } + } } }, "xml": { "name": "Modify_project" } }, - "Drafted_students_project": { + "All_roles": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "role_id": { + "type": "number" + } + } + } + } + }, + "xml": { + "name": "All_roles" + } + }, + "Create_role": { "type": "object", "properties": { - "id": { - "type": "number" - }, "name": { "type": "string" + } + }, + "xml": { + "name": "Create_role" + } + }, + "Student": { + "type": "object", + "properties": { + "evaluation": { + "type": "object", + "properties": { + "evaluations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "decision": { + "type": "string", + "enum": [ + "MAYBE", + "NO", + "YES" + ] + }, + "evaluation_id": { + "type": "number" + }, + "is_final": { + "type": "boolean" + }, + "motivation": { + "type": "string" + } + } + } + }, + "osoc": { + "type": "object", + "properties": { + "year": { + "type": "number" + } + } + } + } + }, + "jobApplication": { + "type": "object", + "properties": { + "applied_role": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AppliedRole" + } + }, + "attachment": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Attachment" + } + }, + "created_at": { + "type": "string", + "example": "This is actually a date: 2022-03-14 23:10:00+01" + }, + "edus": { + "type": "array", + "items": { + "type": "string", + "default": "Informatics" + } + }, + "edu_duration": { + "type": "number" + }, + "edu_institute": { + "type": "string", + "default": "Ghent university" + }, + "edu_level": { + "type": "string", + "default": "Third bachelors degree" + }, + "edu_year": { + "type": "string", + "default": "3" + }, + "email_status": { + "type": "string", + "default": "NONE", + "enum": [ + "DRAFT", + "FAILED", + "NONE", + "SCHEDULED", + "SENT" + ] + }, + "fun_fact": { + "type": "string", + "default": "I like basketball." + }, + "job_application_id": { + "type": "number" + }, + "job_application_skill": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobApplicationSkill" + } + }, + "osoc_id": { + "type": "number" + }, + "responsibilities": { + "type": "string", + "default": "I play basketball from 5pm until 7pm." + }, + "student_coach": { + "type": "boolean" + }, + "student_id": { + "type": "number" + }, + "student_volunteer_info": { + "type": "string", + "default": "Yes, I can work with a student employment agreement in Belgium." + } + } }, - "students": { + "roles": { "type": "array", "items": { - "type": "object", - "properties": { - "status": { - "type": "string", - "enum": [ - "APPROVED", - "CANCELLED", - "DRAFT", - "SENT", - "SIGNED", - "WAIT_APPROVAL" - ] - }, - "student": { - "$ref": "#/components/schemas/Student" - } + "type": "string" + } + }, + "student": { + "type": "object", + "properties": { + "alumni": { + "type": "boolean" + }, + "gender": { + "type": "string" + }, + "nickname": { + "type": "string", + "nullable": true + }, + "person": { + "$ref": "#/components/schemas/Person" + }, + "person_id": { + "type": "number" + }, + "phone_number": { + "type": "string" + }, + "pronouns": { + "type": "string", + "nullable": true + }, + "student_id": { + "type": "number" } } } }, "xml": { - "name": "Drafted_students_project" + "name": "Student" } }, - "Draft_student_project": { + "StudentInfo": { "type": "object", "properties": { - "drafted": { - "type": "boolean" + "evaluation": { + "type": "object", + "properties": { + "evaluations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "evaluation_id": { + "type": "number" + }, + "decision": { + "type": "string", + "enum": [ + "MAYBE", + "NO", + "Yes" + ] + }, + "is_final": { + "type": "boolean" + }, + "motivation": { + "type": "string" + } + } + } + }, + "osoc": { + "type": "number" + } + } }, - "role": { - "type": "string" - } - }, - "xml": { - "name": "Draft_student_project" - } - }, - "Project_conflicts": { - "type": "object", - "properties": { - "data": { + "evaluations": { "type": "array", "items": { "type": "object", "properties": { - "projects": { + "evaluation": { "type": "array", "items": { "type": "object", "properties": { - "id": { - "type": "number" - }, - "name": { - "type": "string" + "login_user": { + "type": "object", + "properties": { + "login_user_id": { + "type": "number" + }, + "person": { + "$ref": "#/components/schemas/Person" + } + } } } } }, - "student": { - "type": "number" - } - } - } - } - }, - "xml": { - "name": "Project_conflicts" - } - }, - "All_roles": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "role_id": { + "osoc": { "type": "number" } } } - } - }, - "xml": { - "name": "All_roles" - } - }, - "Create_role": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - }, - "xml": { - "name": "Create_role" - } - }, - "Student": { - "type": "object", - "properties": { - "evaluations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AllStudentEvaluations" - } }, "jobApplication": { "type": "object", @@ -4010,13 +4043,14 @@ }, "email_status": { "type": "string", - "default": "NONE", + "default": "APPLIED", "enum": [ - "DRAFT", - "FAILED", - "NONE", - "SCHEDULED", - "SENT" + "APPLIED", + "AWAITITING_PROJECT", + "APPROVED", + "CONTRACT_CONFIRMED", + "CONTRACT_DECLINED", + "REJECTED" ] }, "fun_fact": { @@ -4090,7 +4124,7 @@ } }, "xml": { - "name": "Student" + "name": "StudentInfo" } }, "AllStudents": { @@ -4099,64 +4133,48 @@ "data": { "type": "array", "items": { - "$ref": "#/components/schemas/Student" + "$ref": "#/components/schemas/StudentInfo" } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" } }, "xml": { "name": "AllStudents" } }, - "AllStudentEvaluations": { + "AllStudentSuggestions": { "type": "object", "properties": { "evaluation": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Evaluation" - } - }, - "osoc": { "type": "object", "properties": { - "year": { - "type": "number" - } - } - } - }, - "xml": { - "name": "AllStudentEvaluations" - } - }, - "AllStudentSuggestions": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "decision": { - "type": "string", - "enum": [ - "MAYBE" - ] - }, - "evaluation_id": { - "type": "number" - }, - "isFinal": { - "type": "boolean" - }, - "reason": { - "type": "string" - }, - "senderFirstname": { - "type": "string" - }, - "senderLastname": { - "type": "string" + "evaluations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "login_user": { + "type": "object", + "properties": { + "login_user_id": { + "type": "number" + }, + "person": { + "$ref": "#/components/schemas/Person" + } + } + } + } + } + }, + "osoc": { + "type": "object", + "properties": { + "year": { + "type": "number" + } } } } @@ -4166,55 +4184,29 @@ "name": "AllStudentSuggestions" } }, - "Evaluation": { + "PersonAndID": { "type": "object", "properties": { - "decision": { - "type": "string", - "enum": [ - "MAYBE" - ] - }, - "evaluation_id": { + "person_id": { "type": "number" }, - "is_final": { - "type": "boolean" + "email": { + "type": "string" }, - "login_user": { - "type": "object", - "properties": { - "login_user_id": { - "type": "number" - }, - "person": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "firstname": { - "type": "string" - }, - "github": { - "type": "string" - }, - "lastname": { - "type": "string" - }, - "person_id": { - "type": "number" - } - } - } - } + "github": { + "type": "string", + "nullable": true + }, + "github_id": { + "type": "string", + "nullable": true }, - "motivation": { + "name": { "type": "string" } }, "xml": { - "name": "Evaluation" + "name": "PersonAndID" } }, "Person": { @@ -4223,9 +4215,6 @@ "email": { "type": "string" }, - "firstname": { - "type": "string" - }, "github": { "type": "string", "nullable": true @@ -4234,11 +4223,8 @@ "type": "string", "nullable": true }, - "lastname": { + "name": { "type": "string" - }, - "person_id": { - "type": "number" } }, "xml": { @@ -4433,6 +4419,17 @@ "type": "boolean" } } + }, + "Pagination": { + "type": "object", + "properties": { + "page": { + "type": "number" + }, + "count": { + "type": "number" + } + } } } } diff --git a/docs/Deployment diagram.pdf b/docs/Deployment diagram.pdf index c0ca51a4..9d29b1f8 100644 Binary files a/docs/Deployment diagram.pdf and b/docs/Deployment diagram.pdf differ diff --git a/docs/Domain Model/Domeinmodel_version13.drawio b/docs/Domain Model/Domeinmodel_version13.drawio deleted file mode 100644 index 4003178b..00000000 --- a/docs/Domain Model/Domeinmodel_version13.drawio +++ /dev/null @@ -1 +0,0 @@ -7V1bd6O2Fv41ecwsxJ3HxMlMpydt08lMpj0vXcQmNg0GH8CTeH79ETYitjY2si0hOVHXrFWjgIz1bWlrf/uiM2swffmUh7PJb9koSs5MY/RyZl2dmaZpOD7+X9WyWLUg5JirlnEej+q214a7+GdUNxp16zweRcXGjWWWJWU822wcZmkaDcuNtjDPs+fN2x6zZPNbZ+E4Ag13wzCBrd/jUTlZtfqm99r+SxSPJ+SbkRus/jINyc31Lykm4Sh7Xmuyrs+sQZ5l5erT9GUQJdXokXH5/nnxPbl5cj/9+mfxv/Db5X++/n5/vurs4z6PND8hj9Ly4K6fP398fPpx6z6fP06uB/9a99/Non7E+BEm83q8bqO8yNL6F5cLMozFczxNwhRfXT5maXlX/wXh6zCJxyn+PMRvF+W44UeUlzFG4KL+Q5nNcOtwEiejm3CRzavfUJTh8IlcXU6yPP6Juw2Tuk/857yshcl0N+64q57EzQZuzaMC33NLBgY1TTdhUdb3DLMkCWdF/NC88DTMx3F6mZVlNiUdZfN0FI3qqwbp5UWZZ0+N7FTPP8ZJMsiSLF8OjXXlXPtXNm5nhKmGsxql6GVNSGvYPkXZNCrzBb6l/mtg1DDVc9AJ6kn5/CrQyK3vmawJcyO6YT2Jxk3fzdd9wZMuTMd4cJrvM63N70O2wfh97ubXhQkWiDQso8tqeIt18cQf1n7qa9NSaPcQYAQEGN9OCy8e53JNUJPosdwqpsUsHMbp+GZ5zxLWuuVL/Turpgw/+5gsRWQSj0ZRuhShMizDlZRVcjPL4rRcDoRzif/h4RoYH5wzB7/QAF+j12v8r7o9LwdZiqUtjJfiE2ERfo4qMW4RrJ2TuVuwFpt47YvruhhtALoveiZAL5qGcfLmANyxvEzKaVJ/FAUz0djSYLYAzOO4/GX+oHHmirPHqhZE4WwDnB/jvCh/D6eRhpor1Miw2bC2TEFYOwDrJNRQi4DaYtTSPKD+8z59egwG/8TTL4PJvZHeWdnlOYLz+tNy/f789rZa+2ANMGSFfzvWLuMSLmxaewBqAHESL83AejhQq4nUgf8UI1l1RwD/WsnD1TkCQmFBobBaBCAJH6LkNiviMs6q/vPVvZRgSNtmG6z20w5z7ShUfYDqXTkfVT9T2/nq2PkI+ZShb7EKjmVvl5zthj6iDH3LV9fQD4AIv19D32eWLFUMfcIGr8E3WxKNb3ALIQpE6Wa8CzAcR3g1zd8cglw3/HvjzGrGC9sDIkiqzvIsxYNSaKi5Qo3QgQqXH9aQgp1NsjT6fT590DObN9ysprw4uCEVm8bDp1TTNtyxdmWr6xbaBn+aprFGmi/SvmzeHUEyFmD83lmb/W0mxEixC2NtENxw32ALfl5FvJw4b7Nq+i182bhxXzand4LGoyMjkMM4931hcx8yttuJkdWUJ0OWZit5WRvFuulkNQHjYtDMrBNiUCCHu2vXppE+FGnpNAuCVOc2bb6bs2aD+KS1+v7wsrIrviB0TciEAnSjdHRRhb7iq2y2nEhr2zb8x1rxYtu91sTk7lEcTrN09HUSp5SSRjZp+BgnZEccjcYR2SlgLCbZOEvD5Pq1ldpZRy9x+Rd5Dfz576odz9fV1dXL2m1XC3KR4lH7a/1i7anq8vWx5RV5bj8dXmTzfBjtEpTVfXgAxtFOgarhqYZmpzjlURKW8Y/1m3a6X24r8V/39QTuxlbC8ymJW/2k+rFXoYM9WU5HT6sfDXrCQhMu1m6rJ+iOV6biUF3L2/1m9ANO4FDzZ/UOXB1FJmQviZCszTAM7021UJG959oCtjbXmLQj41JFJn4d6F5/4VljPrBvQ4kwM4vgcQsWZAiPHk+iExQZ0H7HE1Jw19XncKkvtV0nwa6jA+x9j3G3jwJRtr8JyTtt1nWuCBYz8qqYdSak7oZ5FJbR6HKx3TeuAT8UcOnWnQlJvX+zh4vZLMHIVCpAo84fdemR8SZk6UbRMC7aVL5G+0i0mYPjxcENybpphreW7Xs8DfixgDPHSQoDvCU8sfgYp+HWXDaN9sFoO7I3bRYDh6cZ2oPx9Rn3aKIoWgsySDcZtlG/FS0RUdpA78FAd6jAeM9lXPDFGegk+lIb6HssBhY78qoY6Bak67oi1zXah6It3Tq3IO02C4viOcs12tzRlm6VW5B8i4uL0TTWNhp3sOUb5RZk3uJikIXDiUabO9rSLXILUjDhcJjNqy16WM63ZrJozA/GXL5driOnROIr2y63GWgX1UOnyGeW0CmIJI8QKOGRTYZLGesOZYOzRjZ59mZHvkV1xCmwyadeuCuuib6fvNe+v0NoGJStaBgUGQsJYVDt6DQ5ceSR7PGxiEoKIT6YQM5IjVAqfqDwwQQZvUEC6Z3T0SkktBad7RVaq4AuImEvnfG4hGbt1FpkNhsfDBJAvyAT3OAilB697NMbHVa95ntUR4GYgF2f0jtBrRO2vhd1vxcE2/XU69M9TFLIyhkfPkCSRoY6s1RTZ2Z/6gzSZ4qoM26gcFJnqDdIIMd1m0dNqJF1gf9WE5z4C4ya/XKTasgfcvxpXH2qAxeM1ud24NuC51bfZ2M800IBrd09UW8py9cuCFtRxzrEJErkSOjphNH+JieMOPt1I84QIKk92TJqvAUma7mfYEeNt+N4FUiVald252rjMUOviivbhvRosSoDqX3Z/OGW7stuTjKBeN9nyRyv5FH+OX3MNPS8oZfu2HYgU47V4wyPQ/wQJ3EZR2+vkpswNOV7rslSsl5Yf55+DIewfq+eu8eiLd1z7UC2o162dbCCGMilO64dyKRkRTbU2zIBYLN6scWBDTmaaDRfGeU6LIW/2WVI341BKqYB/Cb6EekcIf6gW9L3bJBUaUC/muc6E1AQxyJ99waN7gb3v6Mw15hzx9yXvX1zobndYP4Zj0ZczktdqY878BYpXt59Dqoo4GGQ1fIAy38KHWMsBnLpep2U9YYFWy40G8Mfb+n63GUIENMx5Qfjy6q7RcWUu5BsuyjLcDiZvoHT0YS4yEdO5I9ssKrhvxjL/1rFhZPz3KbCKZid58gSJkAtOYSatutYKJpZdzrOc1fX7eofdek+dLelbhceRY00b6Slu8xdyNeVi5m22rkjLd+d3hIXo7f0/PBldaCL2pF5kI0D8OqUHu4pPWSD1JnSQ8JNWVN6jA9GQBzkJKWHZNIdG5hvUak4yDi4DH+TXUC6Mh1BdfitgLKCAmv3q4EH3I0EV3mJPR7kT1VJ7CGCoVBiD8ViC4QFcpxqJPbwA+XUEnu8U85TPebYmD0VIWelRkLmO5VawKjTeBdXCA5NQkWWs9mTS1Nk3NSVt6+6oh5wattMaL0ET90cU0+1HNP+FJGqGab8INkXkeNMI0hivg8tYkjVIiZ304i7GuFm9oCetqgRbksEZGiVWbddaev2casEpEIVWXW5DWi/4wn5xts8+zdqSd/RDmYJ1cSRRUoHdFLSpEIKdxnxIWmp3cid60HADL0qbmQfMl76GGcRSEt3HZM8I53TJRxr6c5jv+WQAKxZ05bzQjTYR4It33/styXoYrivQh3lLwBv6QnZPmShonSk0RaCtvRcbB9yZLM62EIndPDHW3o6tt92NGcxzOOZTtEUYoJJz8f2Ib8FYNbxXwfjy5qiJQxeSLd9yRKoqzXXJqPeIbJZLXNflIAEmmvbfyHwT49rCzTX1g/S0rm2AHJtWqNzg5eVXhMV0B1Adq32n2m9vk2v29fooyNQrwcGrdZZl3txqZgB5OW0Xu9aDoK9z+eWr9chHzdbrQfaucIfbvnKHRJyOV73Ndb8sZbuSAsgGafJV2Fwy3elBZqKE4mv7FTMgCHTVvV4431SKhXJWglYT1cj3Jz4eGOaBTQPDzi2u7ridXyaQ5s4Qcf5afQDVu3cEpq4ggxIZ6oSAU3mvzKZK+cmdYiOuNwVZED6UY0wan6o9BpGjQwGlk91bXKC2SsBa/ZK0Jc2QbQKcEh9gOO1ieNRKwSvNEhE1wdw0O5jpuETlAISpU8g3aqKPmmWAGUUitmfOoHsphrqhCMoPesTyCMu67lFI+1XkOVXACUekcVKSiFkCpMUSEFqz0L3uuAwo6+KawEZkIDUZR6F4y7dx4AMSERqJ4MgtKV7GZChKwCKBJjZryCKd0bohGsA7re16jTfm6VNGfvdD+gtnn2w+Y7orkyqK8HlJxCCLJ8y1jIZHGWs5XPT2nxEoL1MrAH17GV+sPBBJegPk1OuYne6pVkbq0ahAkS0r8ykwwIP1wGgK1GFV5Ft86y8ym+aqVvLrlkCFNJJvRXxREjVenYcYeFUWdXcmDfnptcfSJDswyYUtqB0vSZF6jUhizXWnCy/AixMSBRqSrh7mXGZwVeGEkaQGizKOR5SHW4uAnD5XDCC7ODsNd9Igy4AdPmUsAkZwzh9zPKpPqlbDOTyg8+RCbm7+izXy4We5iIwl17LCRHGaR3zenevT20Whrv0qk7I1Of4CkWYtY6TMJefCUkvALCy3PLpnpDSKNFObtmq8RDNLbtUbXtk0AdxsVLLHsUsO54YYtkD2TF12aWtL0Y94AUb9wuilU3IXipDK5PZf2q19pEJ2UZFKGF+Q9rziEJmbrDa1ePGh+q1LkbTeLfYtgzqVh63UfU0MlA37zv0YIi3obFdmqvTE8nZtosDJZxahIgvqz+/icmQJvwmdbvczJ+G+lTl+DOPqjoTHKrZkUHl/XiGoCRS4Jw2OpJI6T2H24tqh5SnOqrdP1HVbkFKURXVzm1Iex5RSNj9cffHAAyqdsv24JYFJcCawDZplT0RsTG1V3Yfusdix14Zr6wF+bxFFOYaa+5Yy3fIWgzUnuZuDwZYdn1PZEFiCe6TtHnH27wjlH2ndYf6om5bwoIPPt8ahgXTXfFib2m+2a7Xq60mHp3ibNcTgPkBZPdhFFqQmlTGKCRLxukZhZCdVMQo5DekPY/oGyAHT7DInMNaZO4ktQeiuzKOrjLHnRW3FCbtLHmkXTuifaYe2soSf/xgObXUQxtSh/UhAt+KlmM6NYPYQ7EfOrEjCOSX+rE1g3gA6WCfIINoQwZxjpcCHfgrAG35HKINOUR9aIQ4wOUndNgMpKImjQ8GWH6NHxvSU3CT/Ybs/v12Yd3BPUT/KRO4iwyKsg0ONd/pjWUTyMuZ+nVoYtZwdxeEoB8g0T5iiVwbco7KEAVkFitEFPQX12hD6lIRooAfLP2SwfZ7PXFEcqQo2V4rdOQIHSt6OBfsdvTES5vQ9d4Nf3caCHjA8jvUD51oQj0gSP84kA9VR/+od0RJf/rHgaSoKvrnRM8oIUTH2oj+ulE/+u6pUhD0GGu62bRGTuSPbEC74L9YlmGgC4FENKw6b/is1QnoE4U4yhIkKDUV3blyNDPwhKhoB5KTuuq8cNzlk9IO5CiLVv2gwT4WbPmEtAP5Sqzyx/NwrGtKiUBcgQJDDiTekuhHpOe3ALTllxZyIJsXF7d59BjleYT35qu5rrHnj7388kIO5B3j4hL/8HZ7T2N+NOasBYfEYe5CWgsArT3Mh5tlBms0mDiEIT8GEFbWm3DC5xU4rN6E3s4rMOlkZ8M+1J1ggfpUdFfCziug8oZUOa/AhaSpMv4BsgS8S/+ACxlIRfwD/GDp1z/gnnKVwtPVKAGrQmmKf3dqlBeyUKGmeg6pr0VMUd4ubGQiXj5s2BWvgkcendzqdiS30g+QkMFWnfP6eB/Ln4SCh8D51dRxYa/vsnvpUUiT9ZeS5fZeZvEUgOxZ97GGISqj/zpm7EPtzd6mJ/eMyTqklARnPdkwad2K0ttPT5JXqFd5i4+GNKkIqODgU+QsOheN8RA5fivUvrGgkmuUNrP56BqlxgffRZvi4XMRD3tzW0YFagjUNh7kje6iooiz9D/RAh4woKN/eihXZ9LUhsd6iBi9EvDTiB4kPnSET+fK47Fjr0yEjweZlJsMT4lvOuNUDOR9Bvf8eZ8+PQaDf+Lpl8Hk3kjvrOzyvOWsz3uM0+hbWsbv3SHYsmdglQGFA3w8yO29av13jriIKa5AgI/HkG6kXcCHI8wa1CNsh+ZDzgIArA5fsclD7LeT7uQGSBowAzVQb3ZEe2VBmq9BdXFovrATUMwkrwwvitD3DWP3e0Gvcx/5wr6AtFQuzlgyG9WhsKmM9XOL6kIgyeCLKf/Gxz/LDyk+QJHv5YrLRycKHqzCWYzvb//7FP0Mxz+n5zAo7DYsiucsH32JyFdq8kcy+eOyHlXAhfxplRNIEWrqZw33nXNLSeKn9Y0hwadpH3Fw90n6tL4xZPnyatHXUHOHuk+6p/WNIb33Q9N7otDuleppfWV9BIlAdHukeVrf+IQrye23Y17nbnbtV/pmbggRcnylN7ojRZgb19uIgjyauGkFT8DREnvSNrtm1zsjbVqHQoF6b2Ih4oMQDZAQ9qbdawsAup6GcfI1ms7wL4LJu5q9AexNh3N3u3piZm88j5W9CYztoneUdx/a9e+evenAfft0U4K9aX09aM7/8Zxq5kYA1NLDdaB9l4bT916sgT/OfdI2ra8HaRu86SmjFDpmNNTHQd0rZ9P6ftAeKuYP1ZEPGmveWPdZfaf1/aBlNRxqmHnD3Gehndb3Y2Dq3gkNKwBd1pI6HGjY9tdjKKijKg/b/0meFEd7GAm83exRl/O1qVx2n15tFOF8fYsv59s+ZyBj1VPtFGaykGVh2p0hyDvhvNmhbvYgkFaEfFFfsXo9wqROqB6+zLOsXL89D2eT37JRNbTX/wc= \ No newline at end of file diff --git a/docs/Domain Model/Domeinmodel_version13.drawio.png b/docs/Domain Model/Domeinmodel_version13.drawio.png deleted file mode 100644 index 1abccdbe..00000000 Binary files a/docs/Domain Model/Domeinmodel_version13.drawio.png and /dev/null differ diff --git a/docs/Domain Model/Domeinmodel_version14.drawio b/docs/Domain Model/Domeinmodel_version14.drawio new file mode 100644 index 00000000..cdd6429b --- /dev/null +++ b/docs/Domain Model/Domeinmodel_version14.drawio @@ -0,0 +1 @@ +7V1bd5u4Fv41fUwW4s5jkl5OO5mZTNOmM+dlFrGJTYPBB3AT99cfYSNia2MjYwnJqWZ1rTEEZFnflrb2ty96Y13Nnj/k4Xz6ezaOkjemMX5+Y719Y5rI9xD+X3VnWd8xbG99Z5LH4/rey43b+GdEHqzvLuJxVGw9WGZZUsbz7ZujLE2jUbl1L8zz7Gn7sYcs2f7WeTiJwI3bUZjAu9/icTld3/VN7+X+f6J4MiXfjNxg/ZdZSB6uf0kxDcfZ08Yt690b6yrPsnL9afZ8FSXV6JFx+fZx+S25fnQ/fPqr+F/49fK3L3/cna0be3/IK81PyKO07N3008f3D48/btyns4fpu6vv1t03s6hfMX6EyaIer5soL7K0/sXlkgxj8RTPkjDFV5cPWVre1n9B+DpM4kmKP49w76Ic3/gR5WWMEbio/1Bmc3x3NI2T8XW4zBbVbyjKcPRIri6nWR7/xM2GSd0m/nNe1sJkultP3FZv4tsGvptHBX7mhgwMam5dh0VZPzPKkiScF/F90+FZmE/i9DIry2xGGsoW6Tga11cN0quLMs8eG9mp3n+Ik+QqS7J8NTTWW+ed/9bG9xlhquGsRil63hDSGrYPUTaLynyJH6n/Ghg1TPUcdAJ/ff30ItDIrZ+ZbghzI7phPYkmTdvN133Gky5MJ3hwmu8zre3vQ7bB+H3u9teFCRaINCyjy2p4i03xxB82furLrZXQHiDACAgwfpwWXjzO5YagJtFDuVNMi3k4itPJ9eqZFaz1nc/176xuZfjdh2QlItN4PI7SlQiVYRmupaySm3kWp+VqIJxL/A8P15Vx7rxxcIeu8DV6ucb/qsfz8ipLsbSF8Up8IizCT1Elxi2CtXcydwvWchuvQ3HdFKMtQA9FzwToRbMwTl4dgHuWl2k5S+qPomB2TMkwWwDmSVz+Z3GvceaKs8eqFkThbAOcH+K8KP8IZ5GGmivUeBvOhrVlCsLaAVgnoYZaBNQWo5bmAfVfd+njQ3D1bzz7fDW9M9JbK7s8Q3Bef1it3x9f31ZLMtYu4xIubFp7AGoAcRKvzMB6OFCridSB/wwjWTVHAP9SycPbMwSEwoJCYbUIQBLeR8lNVsRlnFXt5+tnKcGQts02WO2nPebaUaj6ANXbcjGufqa289Wx8xHyKUPfYhUcy94tObsNfUQZ+pavrqEfABH+dQ19n1myVDH0CRu8Ad98RTS+wi2EKBClm/EuwHAS4dU0f3UIct0EHowzqxkvbA+IIKk6z7MUD0qhoeYKNUI9FS4/rCEFO59mafTHYnavZzZvuFlNeXFwQyo2jUePqaZtuGPtylbXLbQN/jRLY400X6R92bw7gmQswPhXZ20Ot5kQI8UujLVBcMN9jS34RRXxcuK8zfrW7+Hz1oOHsjmDEzQeHRmBHMa57wub+5Cx3U2MrKc8GbI0W8vLxijWt05WEzAuBs3MOiEGBXK4+3ZtGum+SEunWRCkOndp8/2cNRvEJ63VD4eXlV3xBaFrQiYUoBul44sq9BVfZfPVRNrYtuE/1ooX2+61JiZPj+NwlqXjL9M4pZQ0ssmN93FCdsTReBKRnQLGYppNsjRM3r3cpXbW0XNc/k26gT//U93H83V99fZ547G3S3KR4lH7e/Ni463q8uW11RV57zAdXmSLfBTtE5T1c3gAJtFegarhqYZmrzjlURKW8Y/Nh/a6X24q8d/09QTu1lbC8ymJW/+k+rUXoYMtWU5HS+sfDVrCQhMuNx6rJ+ieLlNxqK7l7e8Z/YITONT8WfeBq6PIhOwlEZKNGYbhva4WKrL33FjANuYak3ZkXKrIxK8D3esvfNOYD+zbUCLMzCJ43IIFGcKjx5PoBEUGdNjxhBTcu+pzuNKX2q6TYNfRAfa+x7jbR4Eo29+E5J026zpXBIsZeVXMOhNSd6M8CstofLnc7RvXgPcFXLp1Z0JS73t2fzGfJxiZSgVo1PmjLj0y3oQs3TgaxUWbytdoH4k2c3C8OLghWTfL8NayfY+nAT8WcOY4SWGAt4QnFu/jNNyZy6bR7o22I3vTZjFweJqh7Y2vz7hHE0XRWpBBus6wjfq1aImI0gb6AAa6QwXGux7jgi/OQCfRl9pAP2AxsNiRV8VAtyBd1xW5rtHui7Z069yCtNs8LIqnLNdoc0dbulVuQfItLi7Gs1jbaNzBlm+UW5B5i4urLBxNNdrc0ZZukVuQgglHo2xRbdHDcrEzk0Vj3htz+Xa5jpwSia9su9xmoF1UD50in1lCpyCSPEKgqMgmhpiotQnEPwTKcLetes+hjHXWECjP3m7It6iGOEVA+VSHuwKg6OdJP4XGP9mKxj8RjCTEP7Wj0yTDkVeyh4ciKimE+GACySI1Yqj4gcIHE2QMBgnkdU5HmZCYWvTmoJhaBZQQiXfpVjpmq7ravSgY5waJnF+SCW5wEUqPWsZ9eofDqqd8j2ooEBOp61P6MKh1ws5+Uc97RrBbT728PcAkhXSccX4O2RkZ6sxSTZ2Zw6kzyJspos64gcJJnaHBIIHk1k0eNTFG1gX+W81s4i8watrLTaohv8/xp0n1qY5YMFrf24NvC547nZ6N1UwLBTRzD0QdoLtLEHaijnWISZTIkdDTmaLDTU4YavZpK8AQIKld2DKKuwUma52fYE9xt+MIFciRah9252rjMUOvig/bhrxosa7/qJ3Y/OGW7sRujjCBeN9lyQKv5FH+MX3INPS8oZfu0XYgRY7V4xyPQ3wfJ3EZR6+vhJswNOW7rMlSsllRf5G+D0ewcK+eu8eiLd1l7UC2o162dZSCGMile6wdyKRkRTbS2zIBYLO6r8WBDTmaaLxYG+U6HoW/2WVI341BKqYB/Dr6EenkIP6gW9L3bJBUaUB/u8h1CqAgjkX67g0a3Q3u/0RhrjHnjrkve/vmQnO7wfwjHo24XJS6RB934C1Stbz7AFRRwMMgq9XJlf8WOrhYDOTS9Tqp5w0rtVxoNoY/3tL1ucsQIKaDyXvjy6q7RQWTu5BsuyjLcDSdvYJj0YS4yMdO5I9tsKrhvxir/1rFhZPz3KbCKZid58gSJkAtyYOatutYKJpZdzrOc1cX7Boedek+dLelYBceRY00b6Slu8xdyNeVy7m22rkjLd+d3hIXo7f0/PBldaCL2pF5kI0D8OqUHu4pPWSD1JnSQ8JNWVN6jHMjIA5yktJDMumODcy3qFQcZPSuv99kF5CmTEdQAX4roKygwNrfNfCCu5WwKi+xx4P8qSqJPUQwFErsoVhsgbBAjlONxB5+oJxaYo93ynmqx5wXc6Ai5KzUSMh8p1ILGHUa72IJQd8kVGQ52y25NEXGTV15h6or6gWnts2E1kvw1M0x9VTLMR1OEamaYcoPkkMROc40giTmr6FFDKlaxORuGnFXI9zMHtDSDjXCbYmADK0y67Yrbd0+bpWAVKgiqy63AR12PCHfeJNn36OW9B3tYJZQRhzZJiNl2RwGzl1GfEhaajdy53oQMEOvihvZh4yXPr9ZBNLSXcckz0jndAnHWrrz2G85HQBr1rTloBAN9pFgy/cf+20Juhjut6GO8heAt/SEbB+yUFE61mgLQVt6LrbfdkZjMcrjuU7ZE4K49IRsH/IdAGYdD9Tb5GLNvxYGL6RfPmcJXLs19yKj/h2yWS01X5SABJp7OXwh8E+Pewk09zIM0tK5lwByL1qjc4OXlW4RFeAbQLal9qdovb5Lr9vv0HtHoF4PDOBTYVzuxaXmBZCn0Xq9azkIDj6oWb5eh/zMfL0eaLKdP9zylTsMYsrxuq+x5o+1dMdKAMm4eb0v0tVVuMMt37USaCpOJL6yU/MChsxL1eNPD0mxUySLIWA9bYtwc+LjT2kW0OwfgGp3NcXrOC2HNnGCjvO0wAt1cUChiQzIgHSmKhGxZP4rk8lwZlIBfeJyGZAB6Uc1wmr5oTJoWC0yGFg+1bXJCWYzBKzZDMFQ2gTRKsAh+eLHaxPHo1YIXmlxiM4Xd9D+Y4ThG5QCEqVPIN2qij5plgBlFIo5nDqB7KYa6oQjKAPrE8gjrup7RWPtV5DlVwAl/5DFSkohZAqTFEhBas9C97rgMKOvimsBGZCA1GX/hOMu3ceADEhEaieDILSlexmQoSvCiQSY2a8gindG6IRrwh22teo035ulTRn73Q/oLZ7d23xHdFMm1ZTgcgQIQZZPGWuZDI4y1vKZOdh56I01oJ69zA8WPqgEw2FyylXNTrdUZ2PVKFSQhvaVmXRYYH8dAJoSVYgT2TbPSpz8ppm6tc2aJUAhnTRYUUeEVK1vxhEWTpU2za15c2Z6w4EEyT5sQmELStfvUaR+T7Pid1LCZPkVYGFColBTwt3LjMsMvjKUMILUYH0+u2YHBQAunwtGkB2cv+QbadAFgC6fEjYhYxinD1k+0yc3i4FcfvA5MiF3V5/tebnU01wE5tJr+yDCOG1iXu/u9Sm+wnCXXuUHmfpcV6EIs1b1EebyMyHpBQBWlls+3RMzGiXayS1bNR6iuWWXqnWODPpgJlZq2aOYZccTQyx7NMFhOft5ZfoFzxgi0cSE7KUytDKZ/adWex2ZkG1UhBLmN6QDjyhk5q7Wu3p8877q1sV4Fu8X25ZB3cnjNqqeRgbq5kOHHgzxLjR2S3N1mh4563TZU8KpRYj4sobzm5gMacKvUrfLzfxpqE9VjsPyqKozQV/Njgyb1qCCkkiBc7o+42hnEim953AHUe2Q8lRHtfvSVHv7wndGx5gJXPksSEuqsj3gBsuw2wMLkn5/3v55BQZVu3YHcO2CMmKI1bUrrDooInaq9uweQhlZ7Ngr49m1ICe4jMJcY80da/lOXYuBHtT8b2+AZdcIRRYkp+A+SZuIvE1EQvt3WohoKPq3JbS495nJMLSYboqXmUhnPTuoo9YQ/QKyh7ATLchWKmMnkhXg5ChgCxKWith4/IZ04BF9BXzhCdadc1jrzp2kMkB0U8bRhef400UK83iWMjyehGxEW1kejx8sp5aNaEMmsD5X4GvRcpKjJgQHqP8Dcj0Ml/VcAXHlf2zNCPYgEewTZARtyAgu8Fqgg4EFoC2fE7QhJ6gPkhAHuPwkD5uBJNQkcG+A5df9sSE/BXfZr8jwP2wb1h3wQ/SfMsG8yKAo2KCv/U7vLJvgXs5UrkNX7SXelJ0do14YJpjXhqSjMkwBmcUKMQXDxTrakLtUhCngB8uwbLD9q55CIjl6lGyvFTqGhI4f7U8Gux0tCdMmzv6q8eCFYQ4hcSC/qY46Ue8UkuHUiQNJTlXUyYkeQ0J4i40R/bRVIvr2sVrv6THW9LFpjZ3IH9uARcF/sSzDQBcCiWVYWN7wWQsQ0IcGcZQlyDdqZrlz5Whm4Akxyw7kGnVheeG4y+eYHUg5Fq36QYN9LNjy+WUH0o9Y5U8W4USXjRKBuAI1hBzIoyXRj0jPbwFoy68e5EByLi5u8ughyvMI783Xc11jzx97+RWEHEgjxsUl/uHt9p7G/GjMWWsKicPchbQWAFo7jPubZQbjlg2JQxjyYwBhZZ0DJ3wkgcPqHBjsSAKTzkU27L7eAQuUoKKbEnYkAZUHpMqRBC4kTZXxD5Al4Jf0D7iQgVTEP8APlmH9A+4pFyI8XY0SsCqUpr53p0Z5JgsVagrkkBIwxBTl7ZFGJuLlkoZN8UpW9WgXs9tR04h+wTK2QqK2dc7L60MsfxJqGgLnV1Nmhb38yv6lRyFNNlyKlTt4JcVTAJJTySs04I6ENTJRGR3aMevva4/4Ll17YJhWn2oRnHVtw8Z1K1vvMF1LulDLncVHy5pUUFTQ+7A5y+9oSfR5o+6h4aGSS5k2s/noUqbGue+ibfHwuYiHvdXmGRXsIXCl8yD3dBsVRZylv0VLeA6BjiAaoCKdSdMjHmv+Kb0S8LMoPUie6CihzpXHY8demSghD7Ix1xmeEl91EqoYyIcMEPrrLn18CK7+jWefr6Z3RnprZZdnLUeC3mGcxl/TMtZORf6Ayw8S8iA/+KL1NeLcEVcgSMhjyEDSbuT+CLMGBgnbofmQswAAq8NXbPMQh+2kO7kBkhnMQA3Umx3Rnl2Q+WtQTfRNIXYCit3klfRFOQVIqvLOfkHP9dYLgny6voBMVS4OXTIb1aHBqST2M4tqQiDJ4IspCcfHx8sPKT5Ake/list7JwrurcJZTu5u/vsY/QwnP2dnMLDsJiyKpywff47IV2ryRzL54zIfNM+D/GmVE0gRaupnA/e9c0tJ4qe1x5Dg07SPOLiHJH1aewxZvrxa9DXU3KEeku5p7TGk935oek8U2oNSPa1d1qeMCER3QJqntccnXFzusB3zJnezb78yOHND12zrXfzNoBrixdzs6DArc3Po8+72aZJHEz2tYAs4nuJAmmffbPzFSJ7WoVCgZJxYiPggRAMkhO1p9/ICgN7Nwjj5Es3m+BfBhGHN9khgezyPle0JjN2id1Q0AOQBNNuzgfveuaUk29PaY2j+//mUaqZHANTSw3ugPZiGM10ggjfOQ9I8rT2GNA/e9JRRCh05GurjoB6U42ntMrSHisV9dWqExpo31kNW/GntMrSsRiMNM2+Yhyzu09plBmbvF6RtOaHLWsaHA23b3mOGIj6q8rbDnOy5yffus1hOhu+1qVx4n145FInU8y2+/G27/EP2SULtlb1TUx0Sl6ScNrvN7RYEUoSQ+5ERpycYJoXD9MpPUeZ///7b49ljuoyWN87F6EdLmF4TmPNnkcGtoCZuwSGhLZm/bHpppxDRaiIwWIlbHmeEtsqJDtMDO8kO3HdPNyWI29buwSVanw4qBOkhedvW7kGKPsPLvUaaO9JDMret3dMRW+LAHfJA0NbuMZz3qqzl37ukHmWl98vt263/+Fv9sIYppwS9oc74DDoK4IEjPrdpgqPN/lawIKc5kNXPbCUyrC9Ou8SdQr3V1t8jIJaOxcIfDhJRtVbbrS5odp3c+r5dxs2y9i7w1cVNlMd4+CoKgaojd24YDS+8bs4OGt54VzW56opu8ig9wl0/eNZ28dUgQOeOF7z8109Z+EFw7tOKxz/3XDFUsU+fGBqY+7tHl3OlKnuLURqCWMiBtQYSyxU38aNDaQ0kqUj3gJjwisE+HhJ8mWdZufl4Hs6nv2fjamjf/R8= \ No newline at end of file diff --git a/docs/Domain Model/Domeinmodel_version14.png b/docs/Domain Model/Domeinmodel_version14.png new file mode 100644 index 00000000..08e91b80 Binary files /dev/null and b/docs/Domain Model/Domeinmodel_version14.png differ diff --git a/docs/README.md b/docs/README.md index fd1f8dcd..af0da459 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,5 @@ -# Documentations -This folder contains all the required documentations: +# Documentation +This folder contains all the required documentation: - [Mock Ups](Mock%20Ups) - [Domain Model](Domain%20Model) - [Use Cases](Use%20cases.pdf) diff --git a/docs/conventions.md b/docs/conventions.md index c97a3556..bb3216eb 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -1,293 +1,2 @@ -This style guide is influenced by https://github.com/basarat/typescript-book/blob/master/docs/styleguide/styleguide.md # TypeScript Style Guide and Coding Conventions - -> An unofficial TypeScript Style Guide - -People have asked me for my opinions on this. Personally I don't enforce these a lot on my teams and projects but it does help to have these mentioned as a tiebreaker when someone feels the need to have such strong consistency. There are other things that I feel much more strongly about and those are covered in the [tips chapter](https://github.com/basarat/typescript-book/blob/master/docs/tips/main.md) (e.g. type assertion is bad, property setters are bad) 🌹. - -Key Sections: - -* [Variable](#variable-and-function) -* [Class](#class) -* [Interface](#interface) -* [Type](#type) -* [Namespace](#namespace) -* [Enum](#enum) -* [`null` vs. `undefined`](#null-vs-undefined) -* [Formatting](#formatting) -* [Single vs. Double Quotes](#quotes) -* [Tabs vs. Spaces](#spaces) -* [Use semicolons](#semicolons) -* [Annotate Arrays as `Type[]`](#array) -* [File Names](#filename) -* [`type` vs `interface`](#type-vs-interface) -* [`==` or `===`](#-or-) -* [Github draft pullrequests](#github-draft-pull-requests) - -## Variable and Function -* Use `camelCase` for variable and function names - -> Reason: Conventional JavaScript - -**Bad** -```ts -var FooVar; -function BarFunc() { } -``` -**Good** -```ts -var fooVar; -function barFunc() { } -``` - -## Class -* Use `PascalCase` for class names. - -> Reason: This is actually fairly conventional in standard JavaScript. - -**Bad** -```ts -class foo { } -``` -**Good** -```ts -class Foo { } -``` -* Use `camelCase` of class members and methods - -> Reason: Naturally follows from variable and function naming convention. - -**Bad** -```ts -class Foo { - Bar: number; - Baz() { } -} -``` -**Good** -```ts -class Foo { - bar: number; - baz() { } -} -``` -## Interface - -* Use `PascalCase` for name. - -> Reason: Similar to class - -* Use `camelCase` for members. - -> Reason: Similar to class - -* **Don't** prefix with `I` - -> Reason: Unconventional. `lib.d.ts` defines important interfaces without an `I` (e.g. Window, Document etc). - -**Bad** -```ts -interface IFoo { -} -``` -**Good** -```ts -interface Foo { -} -``` - -## Type - -* Use `PascalCase` for name. - -> Reason: Similar to class - -* Use `camelCase` for members. - -> Reason: Similar to class - - -## Namespace - -* Use `PascalCase` for names - -> Reason: Convention followed by the TypeScript team. Namespaces are effectively just a class with static members. Class names are `PascalCase` => Namespace names are `PascalCase` - -**Bad** -```ts -namespace foo { -} -``` -**Good** -```ts -namespace Foo { -} -``` - -## Enum - -* Use `PascalCase` for enum names - -> Reason: Similar to Class. Is a Type. - -**Bad** -```ts -enum color { -} -``` -**Good** -```ts -enum Color { -} -``` - -* Use `PascalCase` for enum member - -> Reason: Convention followed by TypeScript team i.e. the language creators e.g `SyntaxKind.StringLiteral`. Also helps with translation (code generation) of other languages into TypeScript. - -**Bad** -```ts -enum Color { - red -} -``` -**Good** -```ts -enum Color { - Red -} -``` - -## Null vs. Undefined - -* Prefer not to use either for explicit unavailability - -> Reason: these values are commonly used to keep a consistent structure between values. In TypeScript you use *types* to denote the structure - -**Bad** -```ts -let foo = { x: 123, y: undefined }; -``` -**Good** -```ts -let foo: { x: number, y?: number } = { x:123 }; -``` - -* Use `undefined` in general (do consider returning an object like `{valid:boolean, value?:Foo}` instead) - -**Bad** -```ts -return null; -``` -**Good** -```ts -return undefined; -``` - -* Use `null` where it's a part of the API or conventional - -> Reason: It is conventional in Node.js e.g. `error` is `null` for NodeBack style callbacks. - -**Bad** -```ts -cb(undefined) -``` -**Good** -```ts -cb(null) -``` - -* Use *truthy* check for **objects** being `null` or `undefined` - -**Bad** -```ts -if (error === null) -``` -**Good** -```ts -if (error) -``` - -* Use `== null` / `!= null` (not `===` / `!==`) to check for `null` / `undefined` on primitives as it works for both `null`/`undefined` but not other falsy values (like `''`, `0`, `false`) e.g. - -**Bad** -```ts -if (error !== null) // does not rule out undefined -``` -**Good** -```ts -if (error != null) // rules out both null and undefined -``` - -## Formatting -The TypeScript compiler ships with a very nice formatting language service. Whatever output it gives by default is good enough to reduce the cognitive overload on the team. - -Use [`tsfmt`](https://github.com/vvakame/typescript-formatter) to automatically format your code on the command line. Also, your IDE (atom/vscode/vs/sublime) already has formatting support built-in. - -Examples: -```ts -// Space before type i.e. foo:string -const foo: string = "hello"; -``` - -## Quotes - -* Prefer double quotes (`"`). - -## Spaces - -* Use `4` spaces or tabs. - -> Reason: The majority of the team use 4 spaces. - -## Semicolons - -* Use semicolons. - -> Reasons: Explicit semicolons helps language formatting tools give consistent results. Missing ASI (automatic semicolon insertion) can trip new devs e.g. `foo() \n (function(){})` will be a single statement (not two). TC39 [warning on this as well](https://github.com/tc39/ecma262/pull/1062). Example teams: [airbnb](https://github.com/airbnb/javascript), [idiomatic](https://github.com/rwaldron/idiomatic.js), [google/angular](https://github.com/angular/angular/), [facebook/react](https://github.com/facebook/react), [Microsoft/TypeScript](https://github.com/Microsoft/TypeScript/). - -## Array - -* Annotate arrays as `foos: Foo[]` instead of `foos: Array`. - -> Reasons: It's easier to read. It's used by the TypeScript team. Makes easier to know something is an array as the mind is trained to detect `[]`. - -## Filename -Name files with `camelCase`. E.g. `accordion.tsx`, `myControl.tsx`, `utils.ts`, `map.ts` etc. - -> Reason: Conventional across many JS teams. - -## type vs. interface - -* Use `type` when you *might* need a union or intersection: - -``` -type Foo = number | { someProperty: number } -``` -* Use `interface` when you want `extends` or `implements` e.g. - -``` -interface Foo { - foo: string; -} -interface FooBar extends Foo { - bar: string; -} -class X implements FooBar { - foo: string; - bar: string; -} -``` -* Otherwise use whatever makes you happy that day. I use [type](https://www.youtube.com/watch?v=IXAT3If0pGI) - -## `==` or `===` -Both are [mostly safe for TypeScript users](https://www.youtube.com/watch?v=vBhRXMDlA18). I use `===` as that is what is used in the TypeScript codebase. - -## Github draft pull requests -* When working on a new branch, create a [draft pull request](https://github.blog/2019-02-14-introducing-draft-pull-requests/) as soon as possible. - ->Reason: A good pull request is as much about collaboration as it is about code. So let your coworkers know what you are working on. - -* **Dont** add a header tag (WIP, DRAFT, DO NOT MERGE...) to your draft pull request . - -> Reason: When draft pull requests were not yet a feature on github, people used these header tags to let their coworkers know that the pull request was not ready to merge yet. This has become obsolete now. +This repository uses [Eslint](https://eslint.org/) in order to have consistent coding style. diff --git a/docs/technicalManual.md b/docs/technicalManual.md index 0e8af8af..9d48f8b5 100644 --- a/docs/technicalManual.md +++ b/docs/technicalManual.md @@ -76,6 +76,11 @@ start the application **WITH DEBUGGER PORTS OPEN** in **local** docker container docker-compose -f "docker-compose.debug.yml" up -d --build ``` +start only the database in **local** docker containers for faster debugging processes +``` +docker-compose -f docker-compose.db.yml up -d --build +``` + shut down the **local** application - shuts down the containers used in the application - removes the containers used in the application @@ -221,10 +226,15 @@ To learn more about Next.js, take a look at the following resources: ## Testing In order to run the tests, make sure the docker daemon is running. -The tests are performed with npm, if it is the first time you want to run the test, consider running `npm install` in the `/backend` folder first. -The test can be executed by running the `npm run integrationTests` command in the `/backend` folder. +The tests are performed with npm, if it is the first time you want to run the test, consider running `npm install` in the folder first. + +### Backend +The tests can be executed by running the `npm run integrationTests` command in the `/backend` folder. + +### Frontend +The tests can be executed by running the `npm run tests` command in the `/frontend` folder. ### Form When creating a new form instance the key for each question will change. To use this new form when deploying or running local tests it's necessary to change the keys in `/backend/routes/form_keys.json` -All these keys are used in `backend/routes/form.ts` and examples of where you can locate them in the json sent by Tally can be found in `/testforms/testform.json` \ No newline at end of file +All these keys are used in `backend/routes/form.ts` and examples of where you can locate them in the json sent by Tally can be found in `/testforms/testform.json` diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 0d4af330..a148ffbd 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18.0.0 +FROM node:18.2.0 # Create app directory WORKDIR /app diff --git a/frontend/__tests__/OsocFilter.test.tsx b/frontend/__tests__/OsocFilter.test.tsx new file mode 100644 index 00000000..6df2db32 --- /dev/null +++ b/frontend/__tests__/OsocFilter.test.tsx @@ -0,0 +1,73 @@ +import "@testing-library/jest-dom"; +import fetchMock from "jest-fetch-mock"; +import { act, render, screen } from "@testing-library/react"; +import fireEvent from "@testing-library/user-event"; +import Osocs from "../pages/osocs"; + +jest.mock("next/router", () => require("next-router-mock")); + +fetchMock.enableMocks(); +jest.mock("next/router"); + +const response = JSON.stringify({ + success: true, + data: [], + pagination: { count: 0 }, +}); +describe("Osoc filter tests", () => { + beforeEach(async () => { + fetchMock.resetMocks(); + fetchMock.mockOnce(response); + fetchMock.mockOnce(response); + await act(async () => { + await render(); + }); + }); + afterEach(() => { + fetchMock.resetMocks(); + }); + test("test rendering osoc filter", () => { + expect(screen.getByTestId("yearSorter")).toBeInTheDocument(); + expect(screen.getByTestId("yearFilter")).toBeInTheDocument(); + expect(screen.getByTestId("searchButton")).toBeInTheDocument(); + }); + + test("filtering osoc edition", async () => { + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("yearSorter")); + }); + let lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/osoc/filter?yearSort=asc¤tPage=0&pageSize=20" + ); + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("yearSorter")); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/osoc/filter?yearSort=desc¤tPage=0&pageSize=20" + ); + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("yearSorter")); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/osoc/filter?currentPage=0&pageSize=20" + ); + }); + + test("test osoc filter", async () => { + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.type(screen.getByTestId("yearFilter"), "2020"); + screen.getByTestId("searchButton").click(); + }); + const lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/osoc/filter?yearFilter=2020¤tPage=0&pageSize=20" + ); + }); +}); diff --git a/frontend/__tests__/SettingsComponent.test.tsx b/frontend/__tests__/SettingsComponent.test.tsx new file mode 100644 index 00000000..6c35815d --- /dev/null +++ b/frontend/__tests__/SettingsComponent.test.tsx @@ -0,0 +1,186 @@ +import { AccountStatus, LoginUser } from "../types"; +import "@testing-library/jest-dom"; +import fetchMock from "jest-fetch-mock"; +import { act, render, screen } from "@testing-library/react"; +import { Settings } from "../components/Settings/Settings"; +import fireEvent from "@testing-library/user-event"; + +fetchMock.enableMocks(); + +describe("User component tests", () => { + let userAdminCoach: LoginUser; + let fetchUser: jest.Mock; + + beforeEach(() => { + fetchUser = jest.fn(); + + userAdminCoach = { + person: { + person_id: -1, + email: "test", + name: "aa", + github: "", + }, + login_user_id: -1, + is_coach: true, + is_admin: true, + account_status: AccountStatus.ACTIVATED, + }; + fetchMock.resetMocks(); + }); + afterEach(() => { + fetchMock.resetMocks(); + }); + + test("test render settings", () => { + render(); + expect(screen.getByTestId("personName")).toBeInTheDocument(); + + expect(screen.getByTestId("personName").textContent).toBe( + "Current Name: " + userAdminCoach.person.name + ); + expect(screen.getByTestId("labelNewName")).toBeInTheDocument(); + expect(screen.getByTestId("labelNewName").textContent).toBe("New Name"); + + expect(screen.getByTestId("inputNewName")).toBeInTheDocument(); + expect(screen.getByTestId("labelCurrentPassword")).toBeInTheDocument(); + + expect(screen.getByTestId("inputCurrentPassword")).toBeInTheDocument(); + expect(screen.getByTestId("errorCurrPass")).toBeInTheDocument(); + expect(screen.getByTestId("labelNewPassword")).toBeInTheDocument(); + expect(screen.getByTestId("inputNewPassword")).toBeInTheDocument(); + + expect( + screen.getByTestId("labelRetypeNewPassword") + ).toBeInTheDocument(); + expect(screen.getByTestId("labelRetypeNewPassword").textContent).toBe( + "Retype New Password" + ); + expect( + screen.getByTestId("inputRetypeNewPassword") + ).toBeInTheDocument(); + expect(screen.getByTestId("confirmButton")).toBeInTheDocument(); + expect(screen.getByTestId("pErrorPassword")).toBeInTheDocument(); + }); + + test("test user input username", async () => { + render(); + await act(async () => { + screen.getByTestId("confirmButton").click(); + }); + expect(screen.getByTestId("pErrorPassword").textContent !== "").toBe( + true + ); + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + await fireEvent.type( + screen.getByTestId("inputNewName"), + "nieuweNaam" + ); + screen.getByTestId("confirmButton").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(1); + fetchMock.mockClear(); + await fireEvent.clear(screen.getByTestId("inputNewName")); + }); + + test("test user current pass", async () => { + render(); + await act(async () => { + await fireEvent.type( + screen.getByTestId("inputCurrentPassword"), + "huidigpass" + ); + screen.getByTestId("confirmButton").click(); + }); + expect(screen.getByTestId("newPassError").textContent !== "").toBe( + true + ); + }); + + test("test user new pass", async () => { + render(); + await act(async () => { + await fireEvent.type( + screen.getByTestId("inputNewPassword"), + "huidignew" + ); + screen.getByTestId("confirmButton").click(); + }); + expect(screen.getByTestId("newPassError").textContent !== "").toBe( + true + ); + }); + + test("test user retype pass", async () => { + render(); + await act(async () => { + await fireEvent.type( + screen.getByTestId("inputRetypeNewPassword"), + "huidignew" + ); + screen.getByTestId("confirmButton").click(); + }); + expect(screen.getByTestId("newPassError").textContent !== "").toBe( + true + ); + }); + + test("test user new not equal retype pass", async () => { + render(); + await act(async () => { + await fireEvent.type( + screen.getByTestId("inputNewPassword"), + "huidignew1" + ); + await fireEvent.type( + screen.getByTestId("inputRetypeNewPassword"), + "huidignew2" + ); + screen.getByTestId("confirmButton").click(); + }); + expect(screen.getByTestId("errorCurrPass").textContent !== "").toBe( + true + ); + expect(screen.getByTestId("newPassError").textContent !== "").toBe( + true + ); + await act(async () => { + await fireEvent.type( + screen.getByTestId("inputCurrentPassword"), + "huidigpass" + ); + screen.getByTestId("confirmButton").click(); + }); + expect(screen.getByTestId("errorCurrPass").textContent === "").toBe( + true + ); + expect(screen.getByTestId("newPassError").textContent !== "").toBe( + true + ); + }); + + test("test user all fields filled correctly", async () => { + render(); + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + await fireEvent.type( + screen.getByTestId("inputCurrentPassword"), + "huidigpass" + ); + await fireEvent.type( + screen.getByTestId("inputNewPassword"), + "huidignew1" + ); + await fireEvent.type( + screen.getByTestId("inputRetypeNewPassword"), + "huidignew1" + ); + screen.getByTestId("confirmButton").click(); + }); + expect(screen.getByTestId("errorCurrPass").textContent === "").toBe( + true + ); + expect(screen.queryByTestId("newPassError")).not.toBeInTheDocument(); + }); +}); diff --git a/frontend/__tests__/StudentFilter.test.tsx b/frontend/__tests__/StudentFilter.test.tsx new file mode 100644 index 00000000..0c8b0700 --- /dev/null +++ b/frontend/__tests__/StudentFilter.test.tsx @@ -0,0 +1,292 @@ +import "@testing-library/jest-dom"; +import fetchMock from "jest-fetch-mock"; +import { act, render, screen } from "@testing-library/react"; +import fireEvent from "@testing-library/user-event"; +import Students from "../pages/students"; + +jest.mock("next/router", () => require("next-router-mock")); + +fetchMock.enableMocks(); +jest.mock("next/router"); +const roles = [ + { role_id: 1, name: "Developer" }, + { role_id: 2, name: "AAA" }, +]; + +const response = JSON.stringify({ + success: true, + data: [], + pagination: { count: 0 }, +}); + +describe("student filter tests", () => { + beforeEach(async () => { + fetchMock.resetMocks(); + + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ + success: true, + }) + ); + fetchMock.mockOnce( + JSON.stringify({ + success: true, + data: roles, + }) + ); + fetchMock.mockOnce(response); + render(); + }); + }); + afterEach(() => { + fetchMock.resetMocks(); + }); + test("test student filter component render", () => { + expect(screen.getByTestId("firstNameSort")).toBeInTheDocument(); + expect(screen.getByTestId("firstNameInput")).toBeInTheDocument(); + expect(screen.getByTestId("emailSort")).toBeInTheDocument(); + expect(screen.getByTestId("emailInput")).toBeInTheDocument(); + expect(screen.getByTestId("osocYearInput")).toBeInTheDocument(); + expect(screen.getByTestId("alumniFilter")).toBeInTheDocument(); + expect(screen.getByTestId("coachFilter")).toBeInTheDocument(); + expect( + screen.getByTestId("rolesSelectedFilterDisplay") + ).toBeInTheDocument(); + expect(screen.getByTestId("statusFilterDisplay")).toBeInTheDocument(); + expect(screen.getByTestId("statusApplied")).toBeInTheDocument(); + expect(screen.getByTestId("statusApproved")).toBeInTheDocument(); + expect(screen.getByTestId("statusAwaiting")).toBeInTheDocument(); + expect(screen.getByTestId("statusConfirmed")).toBeInTheDocument(); + expect(screen.getByTestId("statusDeclined")).toBeInTheDocument(); + expect(screen.getByTestId("statusRejected")).toBeInTheDocument(); + expect(screen.getByTestId("emailFilterYes")).toBeInTheDocument(); + expect(screen.getByTestId("emailFilterMaybe")).toBeInTheDocument(); + expect(screen.getByTestId("emailFilterNo")).toBeInTheDocument(); + expect(screen.getByTestId("searchButton")).toBeInTheDocument(); + }); + + test("test name sort filters", async () => { + await act(async () => { + fetchMock.mockOnce(response); + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("firstNameSort")); + }); + let lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/student/filter?nameSort=asc¤tPage=0&pageSize=10" + ); + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("firstNameSort")); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/student/filter?nameSort=desc¤tPage=0&pageSize=10" + ); + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("firstNameSort")); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/student/filter?currentPage=0&pageSize=10" + ); + const name_text = "first name"; + await act(async () => { + await fireEvent.type( + screen.getByTestId("firstNameInput"), + name_text + ); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?nameFilter=${name_text}¤tPage=0&pageSize=10` + ); + await act(async () => { + await fireEvent.clear(screen.getByTestId("firstNameInput")); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?currentPage=0&pageSize=10` + ); + }); + + test("test email filters", async () => { + await act(async () => { + fetchMock.mockOnce(response); + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("emailSort")); + }); + let lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/student/filter?emailSort=asc¤tPage=0&pageSize=10" + ); + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("emailSort")); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/student/filter?emailSort=desc¤tPage=0&pageSize=10" + ); + await act(async () => { + fetchMock.mockOnce(response); + await fireEvent.click(screen.getByTestId("emailSort")); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/student/filter?currentPage=0&pageSize=10" + ); + const name_text = "email"; + await act(async () => { + await fireEvent.type(screen.getByTestId("emailInput"), name_text); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?emailFilter=${name_text}¤tPage=0&pageSize=10` + ); + await act(async () => { + await fireEvent.clear(screen.getByTestId("emailInput")); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?currentPage=0&pageSize=10` + ); + }); + + test("osoc edition filter", async () => { + const edition = "200"; + await act(async () => { + await fireEvent.type(screen.getByTestId("osocYearInput"), edition); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + let lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?osocYear=${edition}¤tPage=0&pageSize=10` + ); + await act(async () => { + await fireEvent.clear(screen.getByTestId("osocYearInput")); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?currentPage=0&pageSize=10` + ); + }); + + const testButtonHelperFunction1 = async ( + button: string, + valueFilter: string + ) => { + await act(async () => { + fetchMock.mockOnce(response); + screen.getByTestId(button).click(); + }); + const lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?${valueFilter}¤tPage=0&pageSize=10` + ); + }; + + const testButtonHelperFunction2 = async (button: string) => { + await act(async () => { + fetchMock.mockOnce(response); + screen.getByTestId(button).click(); + }); + const lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?currentPage=0&pageSize=10` + ); + }; + const testButtonsFunction = async (button: string, valueFilter: string) => { + await testButtonHelperFunction1(button, valueFilter); + await testButtonHelperFunction2(button); + }; + test("test button filters", async () => { + await testButtonsFunction("alumniFilter", "alumniFilter=true"); + await testButtonsFunction("coachFilter", "coachFilter=true"); + await testButtonsFunction("emailFilterYes", "statusFilter=YES"); + await testButtonsFunction("emailFilterMaybe", "statusFilter=MAYBE"); + await testButtonsFunction("emailFilterNo", "statusFilter=NO"); + }); + + const testEmailFilters = async ( + button: string, + valueFilter: string, + valueDisplay: string + ) => { + await testButtonHelperFunction1(button, valueFilter); + expect(screen.getByTestId("statusFilterDisplay").textContent).toBe( + valueDisplay + ); + await testButtonHelperFunction2(button); + expect(screen.getByTestId("statusFilterDisplay").textContent).toBe( + "No status selected" + ); + }; + + test("test status filters", async () => { + await testEmailFilters( + "statusApplied", + "emailStatusFilter=APPLIED", + "APPLIED" + ); + await testEmailFilters( + "statusApproved", + "emailStatusFilter=APPROVED", + "APPROVED" + ); + await testEmailFilters( + "statusAwaiting", + "emailStatusFilter=AWAITING_PROJECT", + "AWAITING_PROJECT" + ); + await testEmailFilters( + "statusConfirmed", + "emailStatusFilter=CONTRACT_CONFIRMED", + "CONTRACT_CONFIRMED" + ); + }); + + test("test filtering on roles", async () => { + console.log(fetchMock.mock.calls); + expect( + screen.getByTestId("rolesSelectedFilterDisplay").textContent + ).toBe(`No role selected`); + await act(async () => { + screen.getByTestId(`testRoleItem=${roles[0].name}`).click(); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + expect( + screen.getByTestId("rolesSelectedFilterDisplay").textContent + ).toBe(`1 role selected`); + let lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?roleFilter=${roles[0].name}¤tPage=0&pageSize=10` + ); + await act(async () => { + screen.getByTestId(`testRoleItem=${roles[1].name}`).click(); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + expect( + screen.getByTestId("rolesSelectedFilterDisplay").textContent + ).toBe(`2 roles selected`); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/filter?roleFilter=${roles[0].name},${roles[1].name}¤tPage=0&pageSize=10` + ); + }); +}); diff --git a/frontend/__tests__/UserComponent.test.tsx b/frontend/__tests__/UserComponent.test.tsx new file mode 100644 index 00000000..2f5f9c5a --- /dev/null +++ b/frontend/__tests__/UserComponent.test.tsx @@ -0,0 +1,236 @@ +import { User } from "../components/User/User"; +import { AccountStatus, LoginUser } from "../types"; +import "@testing-library/jest-dom"; +import fetchMock from "jest-fetch-mock"; +import { act, render, screen } from "@testing-library/react"; + +fetchMock.enableMocks(); + +const removeUser = jest.fn(); + +describe("User component tests", () => { + let userAdminCoach: LoginUser; + let userInvalid: LoginUser; + let userDisabled: LoginUser; + + beforeEach(() => { + userAdminCoach = { + person: { + person_id: 1, + email: "test", + name: "aga", + github: "", + }, + login_user_id: 1, + is_admin: true, + is_coach: true, + account_status: AccountStatus.ACTIVATED, + }; + userInvalid = { + person: { + person_id: 1, + email: "test", + name: "aa", + github: "", + }, + login_user_id: 1, + is_admin: false, + is_coach: true, + account_status: AccountStatus.PENDING, + }; + userDisabled = { + person: { + person_id: 1, + email: "test", + name: "aa", + github: "", + }, + login_user_id: 1, + is_admin: false, + is_coach: false, + account_status: AccountStatus.DISABLED, + }; + fetchMock.resetMocks(); + }); + afterEach(() => { + fetchMock.resetMocks(); + }); + + test("Test for valid login person", async () => { + render( + + ); + expect(screen.getByTestId("userName")).toBeInTheDocument(); + + expect(screen.getByTestId("userName").firstChild?.nodeValue).toBe( + userAdminCoach.person.name + ); + + expect(screen.queryByTestId("pendingButton")).toBeNull(); + + expect(screen.getByTestId("userEmail")).toBeInTheDocument(); + expect(screen.getByTestId("userEmail").firstChild?.nodeValue).toBe( + userAdminCoach.person.email + ); + }); + + test("test valid login person admin button", async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + render( + + ); + expect(screen.getByTestId("buttonIsAdmin")).toBeInTheDocument(); + expect(screen.getByTestId("imageIsAdmin")).toBeInTheDocument(); + expect(screen.getByAltText("Person is an admin")).toBeInTheDocument(); + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ id: -1, name: "testTest", success: true }) + ); + screen.getByTestId("buttonIsAdmin").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect( + screen.getByAltText("Person is not an admin") + ).toBeInTheDocument(); + + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: false })); + screen.getByTestId("buttonIsAdmin").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(3); + expect( + screen.getByAltText("Person is not an admin") + ).toBeInTheDocument(); + }); + + test("Test is coach for valid person", async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + render( + + ); + expect(screen.getByTestId("buttonIsCoach")).toBeInTheDocument(); + expect(screen.getByTestId("imageIsCoach")).toBeInTheDocument(); + expect(screen.getByAltText("Person is a coach")).toBeInTheDocument(); + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ id: -1, name: "testTest", success: true }) + ); + screen.getByTestId("buttonIsCoach").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect( + screen.getByAltText("Person is not a coach") + ).toBeInTheDocument(); + + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: false })); + screen.getByTestId("buttonIsCoach").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(3); + expect( + screen.getByAltText("Person is not a coach") + ).toBeInTheDocument(); + }); + + test("Test disable valid person", async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + render( + + ); + expect(screen.getByTestId("buttonStatus")).toBeInTheDocument(); + expect(screen.getByTestId("imageStatus")).toBeInTheDocument(); + expect( + screen.getByAltText("Person is not disabled") + ).toBeInTheDocument(); + + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ id: -1, name: "testTest", success: true }) + ); + screen.getByTestId("buttonStatus").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(screen.getByAltText("Person is disabled")).toBeInTheDocument(); + expect( + screen.getByAltText("Person is not a coach") + ).toBeInTheDocument(); + expect( + screen.getByAltText("Person is not an admin") + ).toBeInTheDocument(); + + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: false })); + screen.getByTestId("buttonStatus").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(3); + expect(screen.getByAltText("Person is disabled")).toBeInTheDocument(); + }); + + test("Test delete person", async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + render( + + ); + expect(screen.getByTestId("buttonDelete")).toBeInTheDocument(); + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + screen.getByTestId("buttonDelete").click(); + screen.getByTestId("confirmDelete").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(2); + }); + + test("Test for invalid person", async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + render( + + ); + expect(screen.getByTestId("pendingButton")).not.toBeNull(); + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ id: -1, name: "testTest", success: true }) + ); + screen.getByTestId("pendingButton").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(screen.queryByTestId("pendingButton")).not.toBeInTheDocument(); + }); + + test("Test for disabled person admin", async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + render( + + ); + + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ id: -1, name: "testTest", success: true }) + ); + screen.getByTestId("buttonIsAdmin").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(screen.getByAltText("Person is an admin")).toBeInTheDocument(); + expect( + screen.getByAltText("Person is not disabled") + ).toBeInTheDocument(); + }); + + test("Test for disabled person coach", async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + render( + + ); + + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ id: -1, name: "testTest", success: true }) + ); + screen.getByTestId("buttonIsCoach").click(); + }); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(screen.getByAltText("Person is a coach")).toBeInTheDocument(); + expect( + screen.getByAltText("Person is not disabled") + ).toBeInTheDocument(); + }); +}); diff --git a/frontend/__tests__/login.test.tsx b/frontend/__tests__/login.test.tsx new file mode 100644 index 00000000..cd491d36 --- /dev/null +++ b/frontend/__tests__/login.test.tsx @@ -0,0 +1,191 @@ +import "@testing-library/jest-dom"; +import fetchMock from "jest-fetch-mock"; +import { act, render, screen } from "@testing-library/react"; +import fireEvent from "@testing-library/user-event"; +import Index from "../pages/login"; + +jest.mock("next/router", () => require("next-router-mock")); + +fetchMock.enableMocks(); +jest.mock("next/router"); + +describe("Osoc filter tests", () => { + beforeEach(async () => { + fetchMock.resetMocks(); + fetchMock.mockOnce( + JSON.stringify({ success: true, data: { test: [] } }) + ); + await act(async () => { + render(); + }); + }); + afterEach(() => { + fetchMock.resetMocks(); + }); + + test("test rendering page", async () => { + expect(screen.getByTestId("inputEmailLogin")).toBeInTheDocument(); + expect(screen.getByTestId("loginEmailError")).toBeInTheDocument(); + expect(screen.getByTestId("inputPassLogin")).toBeInTheDocument(); + expect(screen.getByTestId("loginPasswordError")).toBeInTheDocument(); + expect(screen.getByTestId("forgotPassInput")).toBeInTheDocument(); + expect(screen.getByTestId("forgotPassError")).toBeInTheDocument(); + expect(screen.getByTestId("forgotPassConfirm")).toBeInTheDocument(); + expect(screen.getByTestId("loginButton")).toBeInTheDocument(); + expect(screen.getByTestId("backendErrorLogin")).toBeInTheDocument(); + expect(screen.getByTestId("githubLogin")).toBeInTheDocument(); + expect(screen.getByTestId("nameRegister")).toBeInTheDocument(); + expect(screen.getByTestId("errorNameRegister")).toBeInTheDocument(); + expect(screen.getByTestId("emailRegister")).toBeInTheDocument(); + expect(screen.getByTestId("errorEmailRegister")).toBeInTheDocument(); + expect(screen.getByTestId("passwordRegister")).toBeInTheDocument(); + expect(screen.queryByTestId("passStrength")).not.toBeInTheDocument(); + expect(screen.getByTestId("passRegisterError")).toBeInTheDocument(); + expect(screen.getByTestId("rePasswordRegister")).toBeInTheDocument(); + expect( + screen.getByTestId("errorRePasswordRegister") + ).toBeInTheDocument(); + expect(screen.getByTestId("registerButton")).toBeInTheDocument(); + expect(screen.getByTestId("errorBackendRegister")).toBeInTheDocument(); + }); + + const testInputsError = async ( + input: string, + errorField: string, + button: string + ) => { + await act(async () => { + await fireEvent.type(screen.getByTestId(input), "aaaaa@mail.com"); + await screen.getByTestId(button).click(); + }); + expect(screen.getByTestId(errorField).textContent).toBe(""); + await act(async () => { + await fireEvent.clear(screen.getByTestId(input)); + await screen.getByTestId(button).click(); + }); + expect(screen.getByTestId(errorField).textContent !== "").toBe(true); + }; + test("test all inputs", async () => { + await testInputsError( + "inputEmailLogin", + "loginEmailError", + "loginButton" + ); + await testInputsError( + "inputPassLogin", + "loginPasswordError", + "loginButton" + ); + await testInputsError( + "forgotPassInput", + "forgotPassError", + "forgotPassConfirm" + ); + await testInputsError( + "nameRegister", + "errorNameRegister", + "registerButton" + ); + await testInputsError( + "emailRegister", + "errorEmailRegister", + "registerButton" + ); + }); + test("test pass inputs", async () => { + await act(async () => { + await fireEvent.type( + screen.getByTestId("passwordRegister"), + "aaaaa@mail.com" + ); + await screen.getByTestId("registerButton").click(); + }); + expect(screen.getByTestId("passStrength").textContent !== "").toBe( + true + ); + await act(async () => { + await fireEvent.clear(screen.getByTestId("passwordRegister")); + await screen.getByTestId("registerButton").click(); + }); + expect(screen.getByTestId("passRegisterError").textContent !== "").toBe( + true + ); + + await act(async () => { + await fireEvent.type( + screen.getByTestId("rePasswordRegister"), + "aaaaa@mail.com" + ); + await screen.getByTestId("registerButton").click(); + }); + expect( + screen.getByTestId("errorRePasswordRegister").textContent !== "" + ).toBe(true); + const pass = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + await act(async () => { + await fireEvent.type(screen.getByTestId("passwordRegister"), pass); + await fireEvent.clear(screen.getByTestId("rePasswordRegister")); + await fireEvent.type( + screen.getByTestId("rePasswordRegister"), + pass + ); + await screen.getByTestId("registerButton").click(); + }); + expect(screen.getByTestId("errorRePasswordRegister").textContent).toBe( + "" + ); + }); + test("test login all correct", async () => { + await act(async () => { + const email = "mail@mail.com"; + const pass = "pass"; + fetchMock.mockOnce(JSON.stringify({ success: true })); + await fireEvent.type(screen.getByTestId("inputEmailLogin"), email); + await fireEvent.type(screen.getByTestId("inputPassLogin"), pass); + screen.getByTestId("loginButton").click(); + }); + const lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe("undefined/login"); + expect(fetchMock.mock.calls[lastLength][1]?.body).toBe( + '{"pass":"pass","name":"mail@mail.com"}' + ); + }); + + test("register person", async () => { + const email = "mail@mail.com"; + const pass = "ThisIsAStrongPass!"; + const name = "name"; + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + await fireEvent.type(screen.getByTestId("nameRegister"), name); + await fireEvent.type(screen.getByTestId("emailRegister"), email); + await fireEvent.type(screen.getByTestId("passwordRegister"), pass); + await fireEvent.type( + screen.getByTestId("rePasswordRegister"), + pass + ); + screen.getByTestId("registerButton").click(); + }); + const lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + "undefined/user/request" + ); + expect(fetchMock.mock.calls[lastLength][1]?.body).toBe( + `{"name":"${name}","email":"${email}","pass":"${pass}"}` + ); + }); + + test("test send pass reset", async () => { + const email = "mail@mail.com"; + await act(async () => { + fetchMock.mockOnce(JSON.stringify({ success: true })); + await fireEvent.type(screen.getByTestId("forgotPassInput"), email); + screen.getByTestId("forgotPassConfirm").click(); + }); + const lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe("undefined/reset"); + expect(fetchMock.mock.calls[lastLength][1]?.body).toBe( + `{"email":"${email}"}` + ); + }); +}); diff --git a/frontend/__tests__/studentOverview.test.tsx b/frontend/__tests__/studentOverview.test.tsx new file mode 100644 index 00000000..198fc270 --- /dev/null +++ b/frontend/__tests__/studentOverview.test.tsx @@ -0,0 +1,170 @@ +import "@testing-library/jest-dom"; +import fetchMock from "jest-fetch-mock"; +import { act, render, screen } from "@testing-library/react"; +import { StudentOverview } from "../components/StudentOverview/StudentOverview"; +import { AttachmentType, EmailStatus, Student } from "../types"; +import fireEvent from "@testing-library/user-event"; +import { DndProvider } from "react-dnd"; +import { HTML5Backend } from "react-dnd-html5-backend"; + +jest.mock("next/router", () => require("next-router-mock")); + +fetchMock.enableMocks(); +jest.mock("next/router"); + +let student: Student; +describe("student filter tests", () => { + beforeEach(async () => { + fetchMock.resetMocks(); + const attatchment = { + job_application_id: -1, + attachment_id: -1, + data: [""], + type: [AttachmentType.MOTIVATION_STRING], + }; + const jobApplicationSkill = { + is_best: false, + is_preferred: false, + job_application_id: -1, + job_application_skill_id: -1, + language_id: -1, + level: -1, + skill: "", + }; + student = { + evaluation: { + evaluations: [], + osoc: { + year: 2022, + }, + }, + + jobApplication: { + applied_role: [ + { + job_application_id: 1, + applied_role_id: 1, + role_id: 1, + }, + ], + attachment: [attatchment], + created_at: new Date(), + edu_duration: "", + edu_institute: "", + edu_level: "", + edu_year: "", + edus: [""], + email_status: EmailStatus.NONE, + fun_fact: "", + job_application_id: -1, + job_application_skill: [jobApplicationSkill], + osoc_id: -1, + responsibilities: "", + student_coach: false, + student_id: -1, + student_volunteer_info: "", + }, + roles: [""], + student: { + alumni: false, + gender: "", + nickname: "", + person: { + person_id: -1, + email: "", + name: "", + github: "", + github_id: "", + }, + person_id: -1, + phone_number: "", + pronouns: "", + student_id: -1, + }, + }; + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ + success: true, + evaluation: { evaluations: [] }, + }) + ); + fetchMock.mockOnce( + JSON.stringify({ + success: true, + evaluation: { evaluations: [] }, + }) + ); + await render( + + + + ); + }); + }); + afterEach(() => { + fetchMock.resetMocks(); + }); + + test("test rendering osoc filter", () => { + expect(screen.getByTestId("motivationInput")).toBeInTheDocument(); + expect(screen.getByTestId("motivationConfirm")).toBeInTheDocument(); + expect(screen.getByTestId("permanentYes")).toBeInTheDocument(); + expect(screen.getByTestId("permanentNo")).toBeInTheDocument(); + expect(screen.getByTestId("permanentMaybe")).toBeInTheDocument(); + expect(screen.getByTestId("suggestYes")).toBeInTheDocument(); + expect(screen.getByTestId("suggestMaybe")).toBeInTheDocument(); + expect(screen.getByTestId("suggestNo")).toBeInTheDocument(); + }); + + const testButton = async ( + button: string, + query: string, + decision: string, + mode: string + ) => { + const message = "hmmmmmmmmmm..."; + await act(async () => { + fetchMock.mockOnce( + JSON.stringify({ + success: true, + evaluation: { evaluations: [] }, + }) + ); + fetchMock.mockOnce( + JSON.stringify({ + success: true, + evaluation: { evaluations: [] }, + }) + ); + fetchMock.mockOnce( + JSON.stringify({ + success: true, + evaluation: { evaluations: [] }, + }) + ); + screen.getByTestId(button).click(); + await fireEvent.type( + screen.getByTestId("motivationInput"), + message + ); + screen.getByTestId("motivationConfirm").click(); + }); + const lastLength = fetchMock.mock.calls.length - 2; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/student/${student.student.student_id}/${query}` + ); + expect(fetchMock.mock.calls[lastLength][1]?.body).toBe( + `{"id":${student.student.student_id},"${mode}":"${decision}","reason":"${message}","job_application_id":-1}` + ); + fetchMock.mockClear(); + }; + test("test button calls", async () => { + await testButton("permanentYes", "confirm", "YES", "reply"); + await testButton("permanentMaybe", "confirm", "MAYBE", "reply"); + await testButton("permanentNo", "confirm", "NO", "reply"); + await testButton("suggestYes", "suggest", "YES", "suggestion"); + await testButton("suggestMaybe", "suggest", "MAYBE", "suggestion"); + await testButton("suggestNo", "suggest", "NO", "suggestion"); + }); +}); diff --git a/frontend/__tests__/userFilter.test.tsx b/frontend/__tests__/userFilter.test.tsx new file mode 100644 index 00000000..b8bb2144 --- /dev/null +++ b/frontend/__tests__/userFilter.test.tsx @@ -0,0 +1,141 @@ +import "@testing-library/jest-dom"; +import fetchMock from "jest-fetch-mock"; +import { act, render, screen } from "@testing-library/react"; +import fireEvent from "@testing-library/user-event"; +import Users from "../pages/users"; + +jest.mock("next/router", () => require("next-router-mock")); + +fetchMock.enableMocks(); +jest.mock("next/router"); + +const response = JSON.stringify({ + success: true, + data: [], + pagination: { count: 0 }, +}); + +describe("user filter tests", () => { + beforeEach(async () => { + fetchMock.resetMocks(); + await act(async () => { + fetchMock.mockOnce(response); + render(); + }); + }); + afterEach(() => { + fetchMock.resetMocks(); + }); + + test("test user filter component render", () => { + expect(screen.getByTestId("nameSort")).toBeInTheDocument(); + expect(screen.getByTestId("nameInput")).toBeInTheDocument(); + expect(screen.getByTestId("pendingButton")).toBeInTheDocument(); + expect(screen.getByTestId("emailSort")).toBeInTheDocument(); + expect(screen.getByTestId("emailInput")).toBeInTheDocument(); + expect(screen.getByTestId("searchButton")).toBeInTheDocument(); + expect(screen.getByTestId("adminButton")).toBeInTheDocument(); + expect(screen.getByTestId("coachButton")).toBeInTheDocument(); + expect(screen.getByTestId("disabledButton")).toBeInTheDocument(); + }); + const testSortAndInput = async ( + sort: string, + input: string, + sortReqVal: string, + inputReqVal: string + ) => { + await act(async () => { + fetchMock.mockOnce(response); + screen.getByTestId(sort).click(); + }); + let lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/user/filter?${sortReqVal}=asc¤tPage=0&pageSize=20` + ); + await act(async () => { + fetchMock.mockOnce(response); + screen.getByTestId(sort).click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/user/filter?${sortReqVal}=desc¤tPage=0&pageSize=20` + ); + await act(async () => { + fetchMock.mockOnce(response); + screen.getByTestId(sort).click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/user/filter?currentPage=0&pageSize=20` + ); + + const test_val = "testvalue"; + await act(async () => { + await fireEvent.type(screen.getByTestId(input), test_val); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/user/filter?${inputReqVal}=${test_val}¤tPage=0&pageSize=20` + ); + await act(async () => { + await fireEvent.clear(screen.getByTestId(input)); + fetchMock.mockOnce(response); + screen.getByTestId("searchButton").click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/user/filter?currentPage=0&pageSize=20` + ); + }; + + test("test inputs and sorts filters", async () => { + await testSortAndInput( + "nameSort", + "nameInput", + "nameSort", + "nameFilter" + ); + await testSortAndInput( + "emailSort", + "emailInput", + "emailSort", + "emailFilter" + ); + }); + + const testButtonHelperFunction1 = async ( + button: string, + valueFilter: string + ) => { + await act(async () => { + fetchMock.mockOnce(response); + screen.getByTestId(button).click(); + }); + let lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/user/filter?${valueFilter}¤tPage=0&pageSize=20` + ); + await act(async () => { + fetchMock.mockOnce(response); + screen.getByTestId(button).click(); + }); + lastLength = fetchMock.mock.calls.length - 1; + expect(fetchMock.mock.calls[lastLength][0]).toBe( + `undefined/user/filter?currentPage=0&pageSize=20` + ); + }; + test("test buttons presses", async () => { + await testButtonHelperFunction1( + "pendingButton", + "statusFilter=PENDING" + ); + await testButtonHelperFunction1("adminButton", "isAdminFilter=true"); + await testButtonHelperFunction1("coachButton", "isCoachFilter=true"); + await testButtonHelperFunction1( + "disabledButton", + "statusFilter=DISABLED" + ); + }); +}); diff --git a/frontend/components/Filter/OsocFilter/OsocFilter.tsx b/frontend/components/Filter/OsocFilter/OsocFilter.tsx deleted file mode 100644 index 50a4d050..00000000 --- a/frontend/components/Filter/OsocFilter/OsocFilter.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import styles from "../Filter.module.css"; -import React, { SyntheticEvent, useContext, useEffect, useState } from "react"; -import { getNextSort, OsocEdition, Sort } from "../../../types"; -import SessionContext from "../../../contexts/sessionProvider"; -import { useRouter } from "next/router"; - -export const OsocCreateFilter: React.FC<{ - updateOsoc: (osocs: Array) => void; -}> = ({ updateOsoc }) => { - const [osocCreate, setOsocCreate] = useState(""); - const [yearFilter, setYearFilter] = useState(""); - const [yearSort, setYearSort] = useState(Sort.NONE); - const { getSession } = useContext(SessionContext); - const [loading, isLoading] = useState(false); // Check if we are executing a request - - const router = useRouter(); - - /** - * Every time a filter changes we perform a search, on initial page load we also get the filter settings from - * the query parameters - * This makes the filter responsible for all the user data fetching - */ - useEffect(() => { - if (loading) return; - search().then(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [yearSort]); - - const toggleYearSort = async (e: SyntheticEvent) => { - e.preventDefault(); - if (loading) return; - setYearSort(getNextSort(yearSort)); - }; - - /** - * Explicitly tell the frontend to execute the current query - * @param e - */ - const searchPress = async (e: SyntheticEvent) => { - e.preventDefault(); - if (loading) return; - search().then(); - }; - - /** - * Explicitly tell the frontend to execute the current query - * @param e - */ - const createPress = async (e: SyntheticEvent) => { - e.preventDefault(); - if (loading) return; - create().then(); - }; - - /** - * Build and execute the query - */ - const search = async () => { - isLoading(true); - const filters = []; - - if (yearFilter !== "") { - filters.push(`yearFilter=${yearFilter}`); - } - - if (yearSort !== Sort.NONE) { - filters.push(`yearSort=${yearSort}`); - } - - const query = filters.length > 0 ? `?${filters.join("&")}` : ""; - await router.push(`/osocs${query}`); - - const { sessionKey } = getSession - ? await getSession() - : { sessionKey: "" }; - if (sessionKey !== "") { - const response = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/osoc/filter` + query, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - Authorization: `auth/osoc2 ${sessionKey}`, - }, - } - ) - .then((response) => response.json()) - .catch((err) => { - console.log(err); - }); - updateOsoc(response.data); - isLoading(false); - } - }; - - /** - * Create the new osoc edition - */ - const create = async () => { - isLoading(true); - const { sessionKey } = getSession - ? await getSession() - : { sessionKey: "" }; - if (sessionKey !== "") { - const response = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/osoc/create`, - { - method: "POST", - body: JSON.stringify({ - year: osocCreate, - }), - headers: { - "Content-Type": "application/json", - Accept: "application/json", - Authorization: `auth/osoc2 ${sessionKey}`, - }, - } - ) - .then((response) => response.json()) - .catch((err) => { - console.log(err); - }); - console.log(response); - search().then(); - } - }; - - return ( -
    -
    -
    -
    - Year -
    -
    -
    -
    - - setYearFilter(e.target.value)} - /> - -
    - - {/* This shouldn't be a styles query probably */} -
    - setOsocCreate(e.target.value)} - /> - -
    - -
    - ); -}; diff --git a/frontend/components/Filter/StudentFilter/StudentFilter.tsx b/frontend/components/Filter/StudentFilter/StudentFilter.tsx deleted file mode 100644 index f95c9262..00000000 --- a/frontend/components/Filter/StudentFilter/StudentFilter.tsx +++ /dev/null @@ -1,599 +0,0 @@ -import styles from "../Filter.module.css"; -import React, { SyntheticEvent, useContext, useEffect, useState } from "react"; -import { - Display, - EmailStatus, - getNextSort, - Role, - Sort, - Student, - StudentStatus, -} from "../../../types"; -import SessionContext from "../../../contexts/sessionProvider"; -import { useRouter } from "next/router"; -import Image from "next/image"; -import CheckIconColor from "../../../public/images/green_check_mark_color.png"; -import CheckIcon from "../../../public/images/green_check_mark.png"; -import ExclamationIconColor from "../../../public/images/exclamation_mark_color.png"; -import ExclamationIcon from "../../../public/images/exclamation_mark.png"; -import ForbiddenIconColor from "../../../public/images/forbidden_icon_color.png"; -import ForbiddenIcon from "../../../public/images/forbidden_icon.png"; - -export const StudentFilter: React.FC<{ - setFilteredStudents: (user: Array) => void; - display: Display; -}> = ({ setFilteredStudents, display }) => { - const { getSession } = useContext(SessionContext); - const router = useRouter(); - - const [firstNameFilter, setFirstNameFilter] = useState(""); - const [lastNameFilter, setLastNameFilter] = useState(""); - const [emailFilter, setEmailFilter] = useState(""); - const [firstNameSort, setFirstNameSort] = useState(Sort.NONE); - const [lastNameSort, setLastNameSort] = useState(Sort.NONE); - const [emailSort, setEmailSort] = useState(Sort.NONE); - const [alumni, setAlumni] = useState(false); - const [studentCoach, setstudentCoach] = useState(false); - const [statusFilter, setStatusFilter] = useState( - StudentStatus.EMPTY - ); - const [osocYear, setOsocYear] = useState(""); - const [emailStatus, setEmailStatus] = useState( - EmailStatus.EMPTY - ); - - // Roles used in the dropdown - const [roles, setRoles] = useState>([]); - // A set of active roles - const [selectedRoles, setSelectedRoles] = useState>(new Set()); - const [rolesActive, setRolesActive] = useState(false); - const [emailStatusActive, setEmailStatusActive] = useState(false); - - const fetchRoles = async () => { - const { sessionKey } = - getSession != undefined ? await getSession() : { sessionKey: "" }; - const responseRoles = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/role/all`, - { - method: "GET", - headers: { - Authorization: `auth/osoc2 ${sessionKey}`, - }, - } - ) - .then((response) => response.json()) - .then((json) => { - if (!json.success) { - return { success: false }; - } else return json; - }) - .catch((err) => { - console.log(err); - return { success: false }; - }); - setRoles(responseRoles.data); - }; - - /** - * Load data on initial page load - */ - useEffect(() => { - if (router.query.toString() === "/students") { - search().then(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [router.query]); - - useEffect(() => { - if (roles.length === 0) { - fetchRoles().then(); - } - search().then(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ - firstNameSort, - lastNameSort, - emailSort, - alumni, - studentCoach, - statusFilter, - emailStatus, - ]); - - const toggleFirstNameSort = async (e: SyntheticEvent) => { - e.preventDefault(); - setFirstNameSort((prev) => getNextSort(prev)); - }; - - const toggleLastNameSort = async (e: SyntheticEvent) => { - e.preventDefault(); - setLastNameSort((prev) => getNextSort(prev)); - }; - - const toggleEmailSort = async (e: SyntheticEvent) => { - e.preventDefault(); - setEmailSort((prev) => getNextSort(prev)); - }; - - const toggleFilterYes = async (e: SyntheticEvent) => { - e.preventDefault(); - //This is because the call is async - if (statusFilter !== StudentStatus.YES) { - setStatusFilter(() => StudentStatus.YES); - } else { - setStatusFilter(() => StudentStatus.EMPTY); - } - }; - - const toggleFilterMaybe = async (e: SyntheticEvent) => { - e.preventDefault(); - if (statusFilter !== StudentStatus.MAYBE) { - setStatusFilter(() => StudentStatus.MAYBE); - } else { - setStatusFilter(() => StudentStatus.EMPTY); - } - }; - - const toggleFilterNo = async (e: SyntheticEvent) => { - e.preventDefault(); - if (statusFilter !== StudentStatus.NO) { - setStatusFilter(() => StudentStatus.NO); - } else { - setStatusFilter(() => StudentStatus.EMPTY); - } - }; - - const toggleEmailNone = async (e: SyntheticEvent) => { - e.preventDefault(); - if (emailStatus !== EmailStatus.NONE) { - setEmailStatus(() => EmailStatus.NONE); - } else { - setEmailStatus(() => EmailStatus.EMPTY); - } - }; - - const toggleEmailDraft = async (e: SyntheticEvent) => { - e.preventDefault(); - //This is because the call is async - if (emailStatus !== EmailStatus.DRAFT) { - setEmailStatus(() => EmailStatus.DRAFT); - } else { - setEmailStatus(() => EmailStatus.EMPTY); - } - }; - - const toggleEmailSent = async (e: SyntheticEvent) => { - e.preventDefault(); - if (emailStatus !== EmailStatus.SENT) { - setEmailStatus(() => EmailStatus.SENT); - } else { - setEmailStatus(() => EmailStatus.EMPTY); - } - }; - - const toggleEmailFailed = async (e: SyntheticEvent) => { - e.preventDefault(); - if (emailStatus !== EmailStatus.FAILED) { - setEmailStatus(() => EmailStatus.FAILED); - } else { - setEmailStatus(() => EmailStatus.EMPTY); - } - }; - - const toggleEmailScheduled = async (e: SyntheticEvent) => { - e.preventDefault(); - if (emailStatus !== EmailStatus.SCHEDULED) { - setEmailStatus(() => EmailStatus.SCHEDULED); - } else { - setEmailStatus(() => EmailStatus.EMPTY); - } - }; - - const toggleAlumni = async (e: SyntheticEvent) => { - e.preventDefault(); - setAlumni((prev) => !prev); - }; - - const toggleStudentCoach = async (e: SyntheticEvent) => { - e.preventDefault(); - setstudentCoach((prev) => !prev); - }; - - const selectRole = (role: string) => { - // Unselect role - if (selectedRoles.has(role)) { - selectedRoles.delete(role); - } else { - // Select role - selectedRoles.add(role); - } - setSelectedRoles(new Set(selectedRoles)); - }; - - const searchPress = (e: SyntheticEvent) => { - e.preventDefault(); - search().then(); - }; - - const search = async () => { - const filters = []; - if (firstNameFilter !== "") { - filters.push(`firstNameFilter=${firstNameFilter}`); - } - if (firstNameSort !== Sort.NONE) { - filters.push(`firstNameSort=${firstNameSort}`); - } - if (lastNameFilter !== "") { - filters.push(`lastNameFilter=${lastNameFilter}`); - } - if (lastNameSort !== Sort.NONE) { - filters.push(`lastNameSort=${lastNameSort}`); - } - if (emailFilter !== "") { - filters.push(`emailFilter=${emailFilter}`); - } - if (emailSort !== Sort.NONE) { - filters.push(`emailSort=${emailSort}`); - } - if (alumni) { - filters.push(`alumniFilter=${alumni}`); - } - if (studentCoach) { - filters.push(`coachFilter=${studentCoach}`); - } - if (osocYear !== "") { - filters.push(`osocYear=${osocYear}`); - } - if (selectedRoles.size !== 0) { - filters.push( - `roleFilter=${Array.from(selectedRoles.values()).toString()}` - ); - } - if (statusFilter !== StudentStatus.EMPTY) { - filters.push(`statusFilter=${statusFilter}`); - } - if (emailStatus !== EmailStatus.EMPTY) { - filters.push(`emailStatusFilter=${emailStatus}`); - } - const query = filters.length > 0 ? `?${filters.join("&")}` : ""; - // TODO -- setting the url with the filter states is in conflict with the selected student in the url - // await router.push(`/students${query}`); - - const { sessionKey } = getSession - ? await getSession() - : { sessionKey: "" }; - if (sessionKey !== "") { - const response = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/student/filter` + query, - { - method: "GET", - headers: { - Authorization: `auth/osoc2 ${sessionKey}`, - "Content-Type": "application/json", - Accept: "application/json", - }, - } - ) - .then((response) => response.json()) - .then((json) => { - if (!json.success) { - return { success: false }; - } else return json; - }) - .catch((err) => { - console.log(err); - return { success: false }; - }); - setFilteredStudents(response.data); - } - }; - - return ( -
    -
    -
    -
    - Firstname -
    -
    -
    -
    - setFirstNameFilter(e.target.value)} - /> -
    - -
    -
    - Lastname -
    -
    -
    -
    - setLastNameFilter(e.target.value)} - /> -
    - -
    -
    - Email -
    -
    -
    -
    - setEmailFilter(e.target.value)} - /> -
    - -
    - Osoc edition - {/* Maybe dropdown */} - setOsocYear(e.target.value)} - /> -
    -
    - -
    - - - - -
    -
    0 - ? styles.active - : styles.inactive - } ${styles.dropdownTrigger}`} - onClick={() => setRolesActive(!rolesActive)} - > - {selectedRoles.size > 0 - ? selectedRoles.size === 1 - ? `${selectedRoles.size} role selected` - : `${selectedRoles.size} roles selected` - : "No role selected"} -
    -
    -
    -
    -
    -
    - {roles !== undefined - ? roles.map((role) => ( -
    selectRole(role.name)} - > - {role.name} -
    - )) - : null} -
    -
    -
    - -
    -
    setEmailStatusActive(!emailStatusActive)} - > - {emailStatus === EmailStatus.EMPTY - ? "No email selected" - : emailStatus} -
    -
    -
    -
    -
    -
    -
    - {EmailStatus.NONE} -
    -
    - {EmailStatus.DRAFT} -
    -
    - {EmailStatus.SENT} -
    -
    - {EmailStatus.FAILED} -
    -
    - {EmailStatus.SCHEDULED} -
    -
    -
    -
    - -
    -
    - {"Disabled"} -

    YES

    -
    - -
    - {"Disabled"} -

    MAYBE

    -
    - -
    - {"Disabled"} -

    NO

    -
    -
    - - -
    -
    - ); -}; diff --git a/frontend/components/Filter/Filter.module.css b/frontend/components/Filters/Filter.module.css similarity index 90% rename from frontend/components/Filter/Filter.module.css rename to frontend/components/Filters/Filter.module.css index 1a6e2126..7b3bd6e2 100644 --- a/frontend/components/Filter/Filter.module.css +++ b/frontend/components/Filters/Filter.module.css @@ -56,24 +56,25 @@ } /* The filter container */ -.userfilter, .studentfilter, .osocfilter { +.userfilter, .studentfilter, .osocfilter, .projectfilter { background-color: var(--neutral-150); border-radius: 0.5rem; } .userfilter { margin-inline: -0.2rem; - padding: 0.5rem 0.2rem; + padding: 0 0.2rem; } -.studentfilter { +.studentfilter, .projectfilter { display: flex; flex-wrap: wrap; padding: 1rem; gap: 1rem; + justify-content: space-between; } -.studentfilterinputs { +.studentfilterinputs, .projectfilterinput { display: grid; width: 100%; grid-template-columns: 1fr 1fr; @@ -83,7 +84,7 @@ display: contents; } -.studentfilter div, .osocfilter div, .userfilter div { +.studentfilter div, .osocfilter div, .userfilter div, .projectfilter div { justify-content: flex-start; gap: 0.5rem; } @@ -182,12 +183,8 @@ /* Filters that act like checkboxes */ .inactive { background-color: transparent; - border-radius: 0.4rem; border: 0.1rem solid rgba(10, 8, 57, 0.25); color: rgba(10, 8, 57, 0.25); - font-weight: normal; - transition-duration: 0.2s; - font-size: large; } .inactive:hover { @@ -195,14 +192,23 @@ box-shadow: 0 0.2rem 0.4rem rgba(0, 0, 0, 0.25); } +.active, .inactive { + font-size: large; + display: flex; + justify-content: center; + align-items: center; + padding-inline: 1.5rem; + transition-duration: 0.2s; + border-radius: 0.4rem; + font-weight: normal; + min-height: 2.5rem; + gap: 0.5rem; +} + .active { background-color: var(--neutral-100); color: var(--primary-100); - font-weight: normal; - transition-duration: 0.2s; border: 0.1rem solid transparent; - border-radius: 0.4rem; - font-size: large; } .active:hover { diff --git a/frontend/components/Filters/OsocFilter.tsx b/frontend/components/Filters/OsocFilter.tsx new file mode 100644 index 00000000..cd8c0b02 --- /dev/null +++ b/frontend/components/Filters/OsocFilter.tsx @@ -0,0 +1,171 @@ +import styles from "./Filter.module.css"; +import React, { SyntheticEvent, useContext, useEffect, useState } from "react"; +import { + getNextSort, + NotificationType, + OsocFilterParams, + Sort, +} from "../../types"; +import SessionContext from "../../contexts/sessionProvider"; +import { NotificationContext } from "../../contexts/notificationProvider"; +import { useSockets } from "../../contexts/socketProvider"; + +export const OsocCreateFilter: React.FC<{ + search: (params: OsocFilterParams) => void; +}> = ({ search }) => { + const [osocCreate, setOsocCreate] = useState(""); + const [yearFilter, setYearFilter] = useState(""); + const [yearSort, setYearSort] = useState(Sort.NONE); + const { getSession } = useContext(SessionContext); + const { notify } = useContext(NotificationContext); + const { socket } = useSockets(); + + const [isAdmin, setIsAdmin] = useState(false); + + /** + * Every time a filter changes we perform a search, on initial page load we also get the filter settings from + * the query parameters + * This makes the filter responsible for all the user data fetching + */ + useEffect(() => { + if (getSession) { + getSession().then(({ isAdmin }) => { + setIsAdmin(isAdmin); + }); + } + const params: OsocFilterParams = { + yearFilter: yearFilter, + yearSort: yearSort, + }; + search(params); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [yearSort]); + + const toggleYearSort = async (e: SyntheticEvent) => { + e.preventDefault(); + setYearSort(getNextSort(yearSort)); + }; + + /** + * Explicitly tell the frontend to execute the current query + * @param e + */ + const searchPress = async (e: SyntheticEvent) => { + e.preventDefault(); + const params: OsocFilterParams = { + yearFilter: yearFilter, + yearSort: yearSort, + }; + search(params); + }; + + /** + * Explicitly tell the frontend to execute the current query + * @param e + */ + const createPress = async (e: SyntheticEvent) => { + e.preventDefault(); + create().then(); + }; + + /** + * Create the new osoc edition + */ + const create = async () => { + const { sessionKey } = getSession + ? await getSession() + : { sessionKey: "" }; + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/osoc/create`, + { + method: "POST", + body: JSON.stringify({ + year: osocCreate, + }), + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `auth/osoc2 ${sessionKey}`, + }, + } + ) + .then((response) => response.json()) + .catch((err) => { + console.log(err); + }); + if (response && response.success) { + socket.emit("osocCreated"); + const params: OsocFilterParams = { + yearFilter: yearFilter, + yearSort: yearSort, + }; + search(params); + if (notify) { + notify( + "Successfully created a new osoc edition!", + NotificationType.SUCCESS, + 2000 + ); + } + } else if (response && !response.success && notify) { + notify( + "Something went wrong:" + response.reason, + NotificationType.ERROR, + 2000 + ); + } + }; + + return ( +
    +
    +
    +
    + Year +
    +
    +
    +
    + + setYearFilter(e.target.value)} + /> + +
    + + {/** Only admins should be able to create new osoc editions */} + {isAdmin ? ( +
    + setOsocCreate(e.target.value)} + /> + +
    + ) : null} + +
    + ); +}; diff --git a/frontend/components/Filters/ProjectFilter.tsx b/frontend/components/Filters/ProjectFilter.tsx new file mode 100644 index 00000000..eceeeb68 --- /dev/null +++ b/frontend/components/Filters/ProjectFilter.tsx @@ -0,0 +1,206 @@ +import styles from "./Filter.module.css"; +import React, { SyntheticEvent, useEffect, useState } from "react"; +import { getNextSort, ProjectFilterParams, Sort } from "../../types"; + +export const ProjectFilter: React.FC<{ + searchManual: (params: ProjectFilterParams) => void; + searchAutomatic: (params: ProjectFilterParams) => void; +}> = ({ searchManual, searchAutomatic }) => { + const [projectNameFilter, setProjectNameFilter] = useState(""); + const [clientFilter, setClientFilter] = useState(""); + const [fullyAssigned, setFullyAssigned] = useState(false); + const [osocYear, setOsocYear] = useState(""); + const [projectNameSort, setProjectNameSort] = useState(Sort.NONE); + const [clientSort, setClientSort] = useState(Sort.NONE); + + /** + * is executed on first load of the page. + * We parse all the arguments in the URL and apply them to the search + */ + useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + + // get all the arguments from the search string + const clientNameFilter = urlParams.get("clientNameFilter"); + const projectNameFilter = urlParams.get("projectNameFilter"); + const clientNameSort = urlParams.get("clientNameSort"); + const projectNameSort = urlParams.get("projectNameSort"); + const osocYear = urlParams.get("osocYearProject"); + const fullyAssigned = urlParams.get("fullyAssignedFilter"); + + if (clientNameFilter !== null) { + setClientFilter(clientNameFilter); + } + if (projectNameFilter !== null) { + setProjectNameFilter(projectNameFilter); + } + if ( + clientNameSort !== null && + Object.values(Sort).includes(clientNameSort as Sort) + ) { + setClientSort(clientNameSort as Sort); + } + if ( + projectNameSort !== null && + Object.values(Sort).includes(projectNameSort as Sort) + ) { + setProjectNameSort(projectNameSort as Sort); + } + if (osocYear !== null && new RegExp("[0-9]+").test(osocYear)) { + setOsocYear(osocYear); + } + if (fullyAssigned === "true" || fullyAssigned === "false") { + setFullyAssigned(fullyAssigned === "true"); + } + + const params: ProjectFilterParams = { + nameFilter: projectNameFilter ? projectNameFilter : "", + clientFilter: clientNameFilter ? clientNameFilter : "", + fullyAssigned: fullyAssigned === "true", + osocYear: + osocYear && new RegExp("[0-9]+").test(osocYear) ? osocYear : "", + projectNameSort: projectNameSort + ? (projectNameSort as Sort) + : Sort.NONE, + clientSort: clientNameSort ? (clientNameSort as Sort) : Sort.NONE, + }; + + searchAutomatic(params); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const searchPress = () => { + const params: ProjectFilterParams = { + nameFilter: projectNameFilter, + clientFilter: clientFilter, + projectNameSort: projectNameSort, + clientSort: clientSort, + fullyAssigned: fullyAssigned, + osocYear: osocYear, + }; + searchManual(params); + // eslint-disable-next-line react-hooks/exhaustive-deps + }; + + const toggleNameSort = async (e: SyntheticEvent) => { + e.preventDefault(); + setProjectNameSort((prev) => getNextSort(prev)); + + // execute new search + const params: ProjectFilterParams = { + nameFilter: projectNameFilter, + clientFilter: clientFilter, + projectNameSort: getNextSort(projectNameSort), + clientSort: clientSort, + fullyAssigned: fullyAssigned, + osocYear: osocYear, + }; + searchManual(params); + }; + + const toggleClientSort = async (e: SyntheticEvent) => { + e.preventDefault(); + setClientSort((prev) => getNextSort(prev)); + + // execute new search + const params: ProjectFilterParams = { + nameFilter: projectNameFilter, + clientFilter: clientFilter, + projectNameSort: projectNameSort, + clientSort: getNextSort(clientSort), + fullyAssigned: fullyAssigned, + osocYear: osocYear, + }; + searchManual(params); + }; + + const toggleFullyAssigned = async (e: SyntheticEvent) => { + e.preventDefault(); + setFullyAssigned((prev) => !prev); + + // execute new search + const params: ProjectFilterParams = { + nameFilter: projectNameFilter, + clientFilter: clientFilter, + projectNameSort: projectNameSort, + clientSort: clientSort, + fullyAssigned: !fullyAssigned, + osocYear: osocYear, + }; + searchManual(params); + }; + + return ( +
    +
    +
    + Project Name +
    +
    +
    +
    + setProjectNameFilter(e.target.value)} + /> +
    + +
    +
    + Client +
    +
    +
    +
    + setClientFilter(e.target.value)} + /> +
    + +
    + Osoc Edition + {/* Maybe dropdown */} + setOsocYear(e.target.value)} + /> +
    + + + +
    + ); +}; diff --git a/frontend/components/Filters/StudentFilter.tsx b/frontend/components/Filters/StudentFilter.tsx new file mode 100644 index 00000000..034bfe80 --- /dev/null +++ b/frontend/components/Filters/StudentFilter.tsx @@ -0,0 +1,858 @@ +import styles from "./Filter.module.css"; +import React, { SyntheticEvent, useContext, useEffect, useState } from "react"; +import { + Display, + EmailStatus, + getNextSort, + NotificationType, + Role, + Sort, + StudentFilterParams, + StudentStatus, +} from "../../types"; +import SessionContext from "../../contexts/sessionProvider"; +import Image from "next/image"; +import CheckIconColor from "../../public/images/green_check_mark_color.png"; +import CheckIcon from "../../public/images/green_check_mark.png"; +import ExclamationIconColor from "../../public/images/exclamation_mark_color.png"; +import ExclamationIcon from "../../public/images/exclamation_mark.png"; +import ForbiddenIconColor from "../../public/images/forbidden_icon_color.png"; +import ForbiddenIcon from "../../public/images/forbidden_icon.png"; +import { NotificationContext } from "../../contexts/notificationProvider"; + +export const StudentFilter: React.FC<{ + searchManual: (params: StudentFilterParams) => void; + searchAutomatic: (params: StudentFilterParams) => void; + display: Display; +}> = ({ searchManual, searchAutomatic, display }) => { + const { getSession } = useContext(SessionContext); + + const [nameFilter, setNameFilter] = useState(""); + const [emailFilter, setEmailFilter] = useState(""); + const [nameSort, setNameSort] = useState(Sort.NONE); + const [emailSort, setEmailSort] = useState(Sort.NONE); + const [alumni, setAlumni] = useState(false); + const [studentCoach, setStudentCoach] = useState(false); + const [statusFilter, setStatusFilter] = useState( + StudentStatus.EMPTY + ); + const [osocYear, setOsocYear] = useState(""); + const [emailStatus, setEmailStatus] = useState( + EmailStatus.NONE + ); + + // set dropdowns active / inactive + const [rolesActive, setRolesActive] = useState(false); + const [emailStatusActive, setEmailStatusActive] = useState(false); + + // Roles used in the dropdown + const [roles, setRoles] = useState>([]); + // A set of active roles + const [selectedRoles, setSelectedRoles] = useState>(new Set()); + const { notify } = useContext(NotificationContext); + + const fetchRoles = async () => { + const { sessionKey } = getSession + ? await getSession() + : { sessionKey: "" }; + const responseRoles = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/role/all`, + { + method: "GET", + headers: { + Authorization: `auth/osoc2 ${sessionKey}`, + }, + } + ) + .then((response) => response.json()) + .catch((err) => { + console.log(err); + }); + if (responseRoles && responseRoles.data !== undefined) { + setRoles(responseRoles.data); + } else if (responseRoles && !responseRoles.success && notify) { + notify( + "Something went wrong:" + responseRoles.reason, + NotificationType.ERROR, + 2000 + ); + } + }; + + // Load roles on page render + useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + + // get all the arguments from the search string + const nameFilter = urlParams.get("nameFilter"); + const emailFilter = urlParams.get("emailFilter"); + const nameSort = urlParams.get("nameSort"); + const emailSort = urlParams.get("emailSort"); + const alumni = urlParams.get("alumniFilter"); + const studentCoach = urlParams.get("coachFilter"); + const statusFilter = urlParams.get("statusFilter"); + const osocYear = urlParams.get("osocYearStudent"); + const emailStatus = urlParams.get("emailStatusFilter"); + const roleFilter = urlParams.get("roleFilter"); + + // parse all the arguments and set the state + if (nameFilter !== null) { + setNameFilter(nameFilter); + } + if (emailFilter !== null) { + setEmailFilter(emailFilter); + } + if ( + nameSort !== null && + Object.values(Sort).includes(nameSort as Sort) + ) { + setNameSort(nameSort as Sort); + } + if ( + emailSort !== null && + Object.values(Sort).includes(emailSort as Sort) + ) { + setEmailSort(emailSort as Sort); + } + if (alumni === "true" || alumni === "false") { + setAlumni(alumni === "true"); + } + if (studentCoach === "true" || studentCoach === "false") { + setStudentCoach(studentCoach === "true"); + } + if ( + statusFilter !== null && + Object.values(StudentStatus).includes(statusFilter as StudentStatus) + ) { + setStatusFilter(statusFilter as StudentStatus); + } + if (osocYear !== null && new RegExp("[0-9]+").test(osocYear)) { + setOsocYear(osocYear); + } + if ( + emailStatus !== null && + Object.values(EmailStatus).includes(emailStatus as EmailStatus) + ) { + setEmailStatus(emailStatus as EmailStatus); + } + const newRoles = new Set(roleFilter?.split(",")); + setSelectedRoles(newRoles); + + // manually set all the parameters (can't use state yet because setting state is asynchronous) + const params: StudentFilterParams = { + nameFilter: nameFilter ? nameFilter : "", + emailFilter: emailFilter ? emailFilter : "", + nameSort: nameSort ? (nameSort as Sort) : Sort.NONE, + emailSort: emailSort ? (emailSort as Sort) : Sort.NONE, + alumni: alumni === "true", + studentCoach: studentCoach === "true", + statusFilter: statusFilter + ? (statusFilter as StudentStatus) + : StudentStatus.EMPTY, + osocYear: + osocYear && new RegExp("[0-9]+").test(osocYear) ? osocYear : "", + emailStatus: emailStatus + ? (emailStatus as EmailStatus) + : EmailStatus.NONE, + selectedRoles: newRoles, + }; + // search + searchAutomatic(params); + + // execute the fetch roles + fetchRoles().then(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const toggleNameSort = async (e: SyntheticEvent) => { + e.preventDefault(); + setNameSort((prev) => getNextSort(prev)); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: getNextSort(nameSort), + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleEmailSort = async (e: SyntheticEvent) => { + e.preventDefault(); + setEmailSort((prev) => getNextSort(prev)); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: getNextSort(emailSort), + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleFilterYes = async (e: SyntheticEvent) => { + e.preventDefault(); + let newVal; + if (statusFilter !== StudentStatus.YES) { + newVal = StudentStatus.YES; + } else { + newVal = StudentStatus.EMPTY; + } + setStatusFilter(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: newVal, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleFilterMaybe = async (e: SyntheticEvent) => { + e.preventDefault(); + let newVal; + if (statusFilter !== StudentStatus.MAYBE) { + newVal = StudentStatus.MAYBE; + } else { + newVal = StudentStatus.EMPTY; + } + setStatusFilter(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: newVal, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleFilterNo = async (e: SyntheticEvent) => { + e.preventDefault(); + let newVal; + if (statusFilter !== StudentStatus.NO) { + newVal = StudentStatus.NO; + } else { + newVal = StudentStatus.EMPTY; + } + setStatusFilter(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: newVal, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleStatusApplied = async (e: SyntheticEvent) => { + e.preventDefault(); + + let newVal; + if (emailStatus !== EmailStatus.APPLIED) { + newVal = EmailStatus.APPLIED; + } else { + newVal = EmailStatus.NONE; + } + setEmailStatus(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: newVal, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleStatusApproved = async (e: SyntheticEvent) => { + e.preventDefault(); + + let newVal; + if (emailStatus !== EmailStatus.APPROVED) { + newVal = EmailStatus.APPROVED; + } else { + newVal = EmailStatus.NONE; + } + setEmailStatus(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: newVal, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleStatusAwaiting = async (e: SyntheticEvent) => { + e.preventDefault(); + + let newVal; + if (emailStatus !== EmailStatus.AWAITING_PROJECT) { + newVal = EmailStatus.AWAITING_PROJECT; + } else { + newVal = EmailStatus.NONE; + } + setEmailStatus(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: newVal, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleStatusConfirmed = async (e: SyntheticEvent) => { + e.preventDefault(); + + let newVal; + if (emailStatus !== EmailStatus.CONTRACT_CONFIRMED) { + newVal = EmailStatus.CONTRACT_CONFIRMED; + } else { + newVal = EmailStatus.NONE; + } + setEmailStatus(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: newVal, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleStatusDeclined = async (e: SyntheticEvent) => { + e.preventDefault(); + + let newVal; + if (emailStatus !== EmailStatus.CONTRACT_DECLINED) { + newVal = EmailStatus.CONTRACT_DECLINED; + } else { + newVal = EmailStatus.NONE; + } + setEmailStatus(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: newVal, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleStatusRejected = async (e: SyntheticEvent) => { + e.preventDefault(); + + let newVal; + if (emailStatus !== EmailStatus.REJECTED) { + newVal = EmailStatus.REJECTED; + } else { + newVal = EmailStatus.NONE; + } + setEmailStatus(newVal); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: newVal, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleAlumni = async (e: SyntheticEvent) => { + e.preventDefault(); + setAlumni((prev) => !prev); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: !alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const toggleStudentCoach = async (e: SyntheticEvent) => { + e.preventDefault(); + setStudentCoach((prev) => !prev); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: !studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + const selectRole = (role: string) => { + // Unselect role + if (selectedRoles.has(role)) { + selectedRoles.delete(role); + } else { + // Select role + selectedRoles.add(role); + } + + const newRoles = new Set(selectedRoles); + setSelectedRoles(newRoles); + + setEmailStatusActive(false); + setRolesActive(false); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: newRoles, + }; + searchManual(params); + }; + + const searchPress = (e: SyntheticEvent) => { + e.preventDefault(); + const params: StudentFilterParams = { + nameFilter: nameFilter, + emailFilter: emailFilter, + nameSort: nameSort, + emailSort: emailSort, + alumni: alumni, + studentCoach: studentCoach, + statusFilter: statusFilter, + osocYear: osocYear, + emailStatus: emailStatus, + selectedRoles: selectedRoles, + }; + searchManual(params); + }; + + return ( +
    +
    +
    +
    + Name +
    +
    +
    +
    + setNameFilter(e.target.value)} + /> +
    + +
    +
    + Email +
    +
    +
    +
    + setEmailFilter(e.target.value)} + /> +
    + +
    + Osoc Edition + {/* Maybe dropdown */} + setOsocYear(e.target.value)} + /> +
    +
    + +
    + + + + +
    +
    setRolesActive((prev) => !prev)} + data-testid={"rolesSelectedFilterDisplay"} + className={`dropdown-trigger ${ + selectedRoles.size === 0 && !rolesActive + ? styles.inactive + : styles.active + }`} + > + {selectedRoles.size > 0 + ? selectedRoles.size === 1 + ? `${selectedRoles.size} role selected` + : `${selectedRoles.size} roles selected` + : "No role selected"} +
    +
    +
    +
    +
    +
    + {roles !== undefined + ? roles.map((role) => ( +
    selectRole(role.name)} + > + {role.name} +
    + )) + : null} +
    +
    +
    + +
    +
    setEmailStatusActive(!emailStatusActive)} + > + {emailStatus === EmailStatus.NONE + ? "No status selected" + : emailStatus} +
    +
    +
    +
    +
    +
    +
    + {EmailStatus.APPLIED} +
    +
    + {EmailStatus.APPROVED} +
    +
    + {EmailStatus.AWAITING_PROJECT} +
    +
    + {EmailStatus.CONTRACT_CONFIRMED} +
    +
    + {EmailStatus.CONTRACT_DECLINED} +
    +
    + {EmailStatus.REJECTED} +
    +
    +
    +
    + +
    +
    + {"Disabled"} +

    YES

    +
    + +
    + {"Disabled"} +

    MAYBE

    +
    + +
    + {"Disabled"} +

    NO

    +
    +
    + + +
    +
    + ); +}; diff --git a/frontend/components/Filter/UserFilter/UserFilter.tsx b/frontend/components/Filters/UserFilter.tsx similarity index 61% rename from frontend/components/Filter/UserFilter/UserFilter.tsx rename to frontend/components/Filters/UserFilter.tsx index dd6def39..a629fd25 100644 --- a/frontend/components/Filter/UserFilter/UserFilter.tsx +++ b/frontend/components/Filters/UserFilter.tsx @@ -1,20 +1,26 @@ -import styles from "../Filter.module.css"; -import React, { SyntheticEvent, useContext, useEffect, useState } from "react"; +import styles from "./Filter.module.css"; +import React, { SyntheticEvent, useEffect, useState } from "react"; import Image from "next/image"; -import AdminIconColor from "../../../public/images/admin_icon_color.png"; -import AdminIcon from "../../../public/images/admin_icon.png"; -import CoachIconColor from "../../../public/images/coach_icon_color.png"; -import CoachIcon from "../../../public/images/coach_icon.png"; -import ForbiddenIcon from "../../../public/images/forbidden_icon.png"; -import ForbiddenIconColor from "../../../public/images/forbidden_icon_color.png"; -import { AccountStatus, getNextSort, LoginUser, Sort } from "../../../types"; -import SessionContext from "../../../contexts/sessionProvider"; +import AdminIconColor from "../../public/images/admin_icon_color.png"; +import AdminIcon from "../../public/images/admin_icon.png"; +import CoachIconColor from "../../public/images/coach_icon_color.png"; +import CoachIcon from "../../public/images/coach_icon.png"; +import ForbiddenIcon from "../../public/images/forbidden_icon.png"; +import ForbiddenIconColor from "../../public/images/forbidden_icon_color.png"; +import { AccountStatus, getNextSort, Sort } from "../../types"; import { useRouter } from "next/router"; -import { useSockets } from "../../../contexts/socketProvider"; export const UserFilter: React.FC<{ - updateUsers: (users: Array) => void; -}> = ({ updateUsers }) => { + search: ( + nameFilter: string, + nameSort: Sort, + emailFilter: string, + emailSort: Sort, + adminFilter: boolean, + coachFilter: boolean, + statusFilter: AccountStatus + ) => void; +}> = ({ search }) => { const [nameFilter, setNameFilter] = useState(""); const [emailFilter, setEmailFilter] = useState(""); const [nameSort, setNameSort] = useState(Sort.NONE); @@ -24,18 +30,7 @@ export const UserFilter: React.FC<{ const [statusFilter, setStatusFilter] = useState( AccountStatus.NONE ); - const { getSession } = useContext(SessionContext); - const [loading, isLoading] = useState(false); // Check if we are executing a request - const router = useRouter(); - - const { socket } = useSockets(); - - useEffect(() => { - return () => { - socket.off("loginUserUpdated"); - }; // disconnect from the socket on dismount - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useRouter(); /** * Every time a filter changes we perform a search, on initial page load we also get the filter settings from @@ -43,61 +38,40 @@ export const UserFilter: React.FC<{ * This makes the filter responsible for all the user data fetching */ useEffect(() => { - if (loading) return; - search().then(); + search( + nameFilter, + nameSort, + emailFilter, + emailSort, + adminFilter, + coachFilter, + statusFilter + ); // eslint-disable-next-line react-hooks/exhaustive-deps }, [nameSort, emailSort, adminFilter, coachFilter, statusFilter]); - /** - * when the server notifies that a user has changed, we should re-fetch to get the latest changes - * we need the dependency array to make sure we use the latest version of the filter fields - */ - useEffect(() => { - socket.off("loginUserUpdated"); // remove the earlier added listeners - // add new listener - socket.on("loginUserUpdated", () => { - if (loading) return; - search().then(); - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ - socket, - nameFilter, - nameSort, - emailFilter, - emailSort, - statusFilter, - coachFilter, - adminFilter, - ]); - const toggleNameSort = async (e: SyntheticEvent) => { e.preventDefault(); - if (loading) return; setNameSort(getNextSort(nameSort)); }; const toggleEmailSort = async (e: SyntheticEvent) => { e.preventDefault(); - if (loading) return; setEmailSort(getNextSort(emailSort)); }; const toggleAdminFilter = async (e: SyntheticEvent) => { e.preventDefault(); - if (loading) return; setAdminFilter(() => !adminFilter); }; const toggleCoachFilter = async (e: SyntheticEvent) => { e.preventDefault(); - if (loading) return; setCoachFilter(() => !coachFilter); }; const togglePendingStatus = async (e: SyntheticEvent) => { e.preventDefault(); - if (loading) return; if (statusFilter === AccountStatus.PENDING) { setStatusFilter(AccountStatus.NONE); } else { @@ -107,7 +81,6 @@ export const UserFilter: React.FC<{ const toggleDisabledStatus = async (e: SyntheticEvent) => { e.preventDefault(); - if (loading) return; if (statusFilter === AccountStatus.DISABLED) { setStatusFilter(() => AccountStatus.NONE); } else { @@ -121,76 +94,22 @@ export const UserFilter: React.FC<{ */ const searchPress = async (e: SyntheticEvent) => { e.preventDefault(); - if (loading) return; - search().then(); - }; - - /** - * Build and execute the query - */ - const search = async () => { - isLoading(true); - const filters = []; - if (nameFilter !== "") { - filters.push(`nameFilter=${nameFilter}`); - } - - if (nameSort !== Sort.NONE) { - filters.push(`nameSort=${nameSort}`); - } - - if (emailFilter !== "") { - filters.push(`emailFilter=${emailFilter}`); - } - - if (emailSort !== Sort.NONE) { - filters.push(`emailSort=${emailSort}`); - } - - if (adminFilter) { - filters.push(`isAdminFilter=${adminFilter}`); - } - - if (coachFilter) { - filters.push(`isCoachFilter=${coachFilter}`); - } - - if (statusFilter !== AccountStatus.NONE) { - filters.push(`statusFilter=${statusFilter}`); - } - - const query = filters.length > 0 ? `?${filters.join("&")}` : ""; - await router.push(`/users${query}`); - - const { sessionKey } = getSession - ? await getSession() - : { sessionKey: "" }; - if (sessionKey !== "") { - const response = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/user/filter` + query, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - Authorization: `auth/osoc2 ${sessionKey}`, - }, - } - ) - .then((response) => response.json()) - .catch((err) => { - console.log(err); - }); - updateUsers(response.data); - } - isLoading(false); + search( + nameFilter, + nameSort, + emailFilter, + emailSort, + adminFilter, + coachFilter, + statusFilter + ); }; return (
    -
    +
    Names
    Pending
    -
    +
    Email
    setEmailFilter(e.target.value)} /> - +
    { const { @@ -17,6 +18,10 @@ export const Header: React.FC = () => { setIsVerified, } = useContext(SessionContext); + const { fetchIsVerified } = useContext(SessionContext); + + const { socket } = useSockets(); + const router = useRouter(); const logIn = (e: SyntheticEvent) => { @@ -24,6 +29,18 @@ export const Header: React.FC = () => { router.push("/login").then(); }; + useEffect(() => { + socket.off("loginUserDisabled"); // remove old listeners + + // when receiving that a loginUser was disabled => fetch from the server to check if session key is still valid + // getSession wil redirect automatically to /login if the key is invalid + socket.on("loginUserDisabled", () => { + if (fetchIsVerified) { + fetchIsVerified().then(); + } + }); + }, [fetchIsVerified, sessionKey, socket]); + const logOut = (e: SyntheticEvent) => { e.preventDefault(); if (setSessionKey) { diff --git a/frontend/components/Labels/Label.tsx b/frontend/components/Labels/Label.tsx new file mode 100644 index 00000000..a370e500 --- /dev/null +++ b/frontend/components/Labels/Label.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import styles from "./Labels.module.scss"; + +// Maps a number to a color +const colors = [ + styles.blue, + styles.green, + styles.yellow, + styles.red, + styles.other, +]; + +/** + * We set the label color using the sum of character codes module the amount of available colors + * This way every label that has the same value has the same coloring + * @param label + */ +const getLabelColor = (label: string) => { + let color = 0; + for (let i = 0; i < label.length; i++) { + color += label.charCodeAt(i) % colors.length; + } + color %= colors.length; + + return colors[color]; +}; + +/** + * A general purpose label that is colored corresponding to the given input + * @param language + * @constructor + */ +export const Label: React.FC<{ label: string }> = ({ label }) => { + return ( +
    {label}
    + ); +}; diff --git a/frontend/components/Labels/LanguageAndSkill.tsx b/frontend/components/Labels/LanguageAndSkill.tsx deleted file mode 100644 index 3a89a908..00000000 --- a/frontend/components/Labels/LanguageAndSkill.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from "react"; -import styles from "./Labels.module.scss"; - -// Maps a number to a color -const colors = [ - styles.blue, - styles.green, - styles.yellow, - styles.red, - styles.other, -]; - -/** - * We set the label color using the sum of character codes module the amount of available colors - * This way every label that has the same value has the same coloring - * @param label - */ -const getLabelColor = (label: string) => { - let color = 0; - for (let i = 0; i < label.length; i++) { - color += label.charCodeAt(i) % colors.length; - } - color %= colors.length; - - return colors[color]; -}; - -// Maps a skill to a color -const languageToStyle = new Map(); -languageToStyle.set("Dutch", styles.blue); -languageToStyle.set("English", styles.green); -languageToStyle.set("French", styles.yellow); -languageToStyle.set("German", styles.red); - -const getLanguageStyle = (language: string) => { - if (languageToStyle.has(language)) { - return languageToStyle.get(language); - } - - return getLabelColor(language); -}; - -/** - * A label that is colored corresponding to the given language - * @param language - * @constructor - */ -export const LanguageAndSkill: React.FC<{ language: string }> = ({ - language, -}) => { - return ( -
    - {language} -
    - ); -}; diff --git a/frontend/components/Labels/ProjectRole.tsx b/frontend/components/Labels/ProjectRole.tsx new file mode 100644 index 00000000..8192cfc2 --- /dev/null +++ b/frontend/components/Labels/ProjectRole.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import styles from "./Labels.module.scss"; + +// Maps a number to a color +const colors = [ + styles.blue, + styles.green, + styles.yellow, + styles.red, + styles.other, +]; + +/** + * We set the label color using the sum of character codes module the amount of available colors + * This way every label that has the same value has the same coloring + * @param label + */ +const getLabelColor = (label: string) => { + let color = 0; + for (let i = 0; i < label.length; i++) { + color += label.charCodeAt(i) % colors.length; + } + color %= colors.length; + + return colors[color]; +}; + +/** + * A label that is colored corresponding to the given input + * used in project assigned roles + * @param label + * @param posisions Amount of filled positions of form X/Y + * @constructor + */ +export const ProjectRole: React.FC<{ label: string; positions: string }> = ({ + label, + positions, +}) => { + return ( +
    + {positions} {label} +
    + ); +}; diff --git a/frontend/components/Labels/Roles.tsx b/frontend/components/Labels/Roles.tsx deleted file mode 100644 index 4caf0bcc..00000000 --- a/frontend/components/Labels/Roles.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from "react"; -import styles from "./Labels.module.scss"; - -/** - * Maps a role to a color and a better string representation - */ -const roleToStyle = new Map(); -roleToStyle.set("Back-end developer", ["Backend Developer", styles.blue]); -roleToStyle.set("Business Modeller", ["Business Modeller", styles.green]); -roleToStyle.set("Storyteller", ["Storyteller", styles.yellow]); -roleToStyle.set("UX / UI designer", ["UX / UI Designer", styles.red]); -roleToStyle.set("Graphic designer", ["Graphic Designer", styles.other]); -roleToStyle.set("Front-end developer", ["Frontend Developer", styles.blue]); -roleToStyle.set("Marketer", ["Marketer", styles.green]); -roleToStyle.set("Photographer", ["Photographer", styles.yellow]); -roleToStyle.set("Video editor", ["Video Editor", styles.red]); -roleToStyle.set("Copywriter", ["Copywriter", styles.yellow]); - -const getRoleStyle = (role: string) => { - if (roleToStyle.has(role)) { - return roleToStyle.get(role); - } - - return [role, styles.other]; -}; - -/** - * A label that is colored corresponding to the given role - * @param role - * @constructor - */ -export const Role: React.FC<{ role: string }> = ({ role }) => { - const styleAndString = getRoleStyle(role); - const betterRole = styleAndString ? styleAndString[0] : role; - const style = styleAndString ? styleAndString[1] : styles.other; - return
    {betterRole}
    ; -}; diff --git a/frontend/components/Labels/Studies.tsx b/frontend/components/Labels/Studies.tsx deleted file mode 100644 index 8f504d4c..00000000 --- a/frontend/components/Labels/Studies.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from "react"; -import styles from "./Labels.module.scss"; - -/** - * Maps a study to a color and better string representation - */ -const studyToStyle = new Map(); -studyToStyle.set("Backend development", ["Backend Development", styles.blue]); -studyToStyle.set("Business management", ["Business Management", styles.green]); -studyToStyle.set("Communication Sciences", [ - "Communication Sciences", - styles.yellow, -]); -studyToStyle.set("Computer Sciences", ["Computer Sciences", styles.red]); -studyToStyle.set("Design", ["Design", styles.other]); -studyToStyle.set("Frontend development", ["Frontend Development", styles.blue]); -studyToStyle.set("Marketing", ["Marketing", styles.green]); -studyToStyle.set("Photography", ["Photography", styles.yellow]); -studyToStyle.set("Videography", ["Videography", styles.red]); - -const getStudyStyle = (study: string) => { - if (studyToStyle.has(study)) { - return studyToStyle.get(study); - } - - return [study, styles.other]; -}; - -/** - * A label that is colored corresponding to the given study - * @param role - * @constructor - */ -export const Study: React.FC<{ study: string }> = ({ study }) => { - const styleAndString = getStudyStyle(study); - const betterStudy = styleAndString ? styleAndString[0] : study; - const style = styleAndString ? styleAndString[1] : styles.other; - return
    {betterStudy}
    ; -}; diff --git a/frontend/components/Modal/Modal.module.scss b/frontend/components/Modal/Modal.module.scss index 23781d05..2b86774b 100644 --- a/frontend/components/Modal/Modal.module.scss +++ b/frontend/components/Modal/Modal.module.scss @@ -1,41 +1,13 @@ -.modal { - position: fixed; - top: 0; - left: 0; - width:100%; - height: 100%; - background: rgba(0, 0, 0, 0.6); - z-index: 9999; -} - -.modalMain { - position:fixed; - background: var(--neutral-100); - width: clamp(10rem, 90vw, 35rem); - height: auto; - left:50%; - margin-top: 20rem; - transform: translate(-50%,-50%); - display: flex; - flex-direction: column; - padding: 1.5rem; -} - .header { - display: flex; - margin-bottom: 1rem; - justify-content: space-between; - align-items: center; -} - -.displayBlock { - display: block; + background-color: var(--error-100); } -.displayNone { - display: none; +.header > button { + padding: 0; } -.modal .modalMain button { - align-self: flex-end; +.body { + display: flex; + flex-direction: column; + gap: 1rem; } diff --git a/frontend/components/Modal/Modal.tsx b/frontend/components/Modal/Modal.tsx index 66e634d2..364e4a1f 100644 --- a/frontend/components/Modal/Modal.tsx +++ b/frontend/components/Modal/Modal.tsx @@ -16,23 +16,22 @@ export const Modal: React.FC<{ handleClose: (e: SyntheticEvent) => void; }> = ({ children, visible, handleClose, title }) => { return ( -
    -
    -
    -

    {title}

    +
    +
    +
    +
    +

    {title}

    -
    - {children} + +
    + {children} +
    ); diff --git a/frontend/components/Notification/Notification.module.scss b/frontend/components/Notification/Notification.module.scss new file mode 100644 index 00000000..8272dc1c --- /dev/null +++ b/frontend/components/Notification/Notification.module.scss @@ -0,0 +1,21 @@ +.notification { + animation: fadein 0.5s; + z-index: 999; +} + +@keyframes fadein { + from { opacity: 0; } + to { opacity: 1; } +} + +.success { + background-color: var(--succes-100); +} + +.warning { + background-color: var(--warning-100); +} + +.error { + background-color: var(--error-100); +} diff --git a/frontend/components/Notification/Notification.tsx b/frontend/components/Notification/Notification.tsx new file mode 100644 index 00000000..ac5d5d6f --- /dev/null +++ b/frontend/components/Notification/Notification.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import { NotificationType } from "../../types"; +import styles from "./Notification.module.scss"; + +export const Notification: React.FC<{ + message: string; + index: number; + onDelete: (index: number) => void; + type: NotificationType; +}> = ({ message, index, onDelete, type }) => { + return ( +
    +
    onDelete(index)} /> +

    {message}

    +
    + ); +}; diff --git a/frontend/components/Osoc/Osoc.tsx b/frontend/components/Osoc/Osoc.tsx index c8c5aefe..deaf1810 100644 --- a/frontend/components/Osoc/Osoc.tsx +++ b/frontend/components/Osoc/Osoc.tsx @@ -1,7 +1,10 @@ import styles from "./Osoc.module.css"; import React, { SyntheticEvent, useContext, useState } from "react"; import SessionContext from "../../contexts/sessionProvider"; -import { OsocEdition } from "../../types"; +import { NotificationType, OsocEdition } from "../../types"; +import { Modal } from "../Modal/Modal"; +import { NotificationContext } from "../../contexts/notificationProvider"; +import { useSockets } from "../../contexts/socketProvider"; export const Osoc: React.FC<{ osoc: OsocEdition; @@ -9,12 +12,15 @@ export const Osoc: React.FC<{ }> = ({ osoc, removeOsoc }) => { const [year] = useState(osoc.year); const [projects] = useState(osoc._count.project); - const { sessionKey } = useContext(SessionContext); + const { sessionKey, isAdmin } = useContext(SessionContext); const osocId = osoc.osoc_id; + const [showDeleteModal, setShowDeleteModal] = useState(false); + const { notify } = useContext(NotificationContext); + const { socket } = useSockets(); const deleteOsoc = async (e: SyntheticEvent) => { e.preventDefault(); - await fetch( + const response = await fetch( `${process.env.NEXT_PUBLIC_API_URL}/osoc/` + osocId.toString(), { method: "DELETE", @@ -27,16 +33,35 @@ export const Osoc: React.FC<{ ) .then((response) => response.json()) .then(async (json) => { - if (!json.success) { - return { success: false }; + if (json.success) { + removeOsoc(osoc); } - removeOsoc(osoc); return json; }) .catch((err) => { - console.log(err); + if (notify) { + notify( + "Something went wrong:" + err, + NotificationType.ERROR, + 2000 + ); + } return { success: false }; }); + if (response && response.success && notify) { + socket.emit("osocDeleted"); + notify( + "Successfully deleted osoc edition!", + NotificationType.SUCCESS, + 2000 + ); + } else if (response && !response.success && notify) { + notify( + "Something went wrong:" + response.reason, + NotificationType.ERROR, + 2000 + ); + } }; return ( @@ -46,10 +71,25 @@ export const Osoc: React.FC<{

    # Projects: {projects}

    - + + {/* Only admins can delete osoc editions */} + {isAdmin ? ( +
    ); }; diff --git a/frontend/components/Paginator/Paginator.tsx b/frontend/components/Paginator/Paginator.tsx new file mode 100644 index 00000000..bee665c2 --- /dev/null +++ b/frontend/components/Paginator/Paginator.tsx @@ -0,0 +1,65 @@ +import { Pagination } from "../../types"; +import React from "react"; + +export const Paginator: React.FC<{ + pageSize: number; + pagination: Pagination; + navigator: (page: number) => void; +}> = ({ pageSize, pagination, navigator }) => { + const paginator = []; + const pages = Math.ceil(pagination.count / pageSize); + for (let i = 0; i < pages; i++) { + paginator.push( +
  • + navigator(i)} + className={`pagination-link ${ + i === pagination.page ? "is-current" : "" + }`} + > + {i + 1} + +
  • + ); + } + + const previousPage = () => { + if (pagination.page === 0) return; + navigator(pagination.page - 1); + }; + + const nextPage = () => { + if (pagination.page === pages - 1) return; + navigator(pagination.page + 1); + }; + + return ( + + ); +}; diff --git a/frontend/components/ProjectCard/ProjectCard.module.css b/frontend/components/ProjectCard/ProjectCard.module.css new file mode 100644 index 00000000..8ddada3a --- /dev/null +++ b/frontend/components/ProjectCard/ProjectCard.module.css @@ -0,0 +1,105 @@ +.body { + padding: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.body > header { + display: flex; + justify-content: space-between; + gap: 2rem; +} + +.left { + display: flex; + justify-content: flex-start; + align-items: stretch; + flex-wrap: wrap; + flex-direction: column; +} + +.left > div { + display: flex; + gap: 1rem; + flex-wrap: wrap; +} + +.left > div > p { + align-self: end; + opacity: 80%; +} + +.left > h3 { + opacity: 80%; +} + +.coaches { + margin-inline: -0.2rem; + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + align-items: flex-start; +} + +.roles { + margin-top: 0.5rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + align-content: flex-end; + justify-content: flex-start; + align-items: flex-end; +} + +/* The actual card as a container */ +.card { + box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.5); + border-radius: 0.5rem; + display: flex; + flex-direction: column; + cursor: pointer; + width: 100%; +} + +.assignees { + margin-top: 0.5rem; + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: flex-start; +} + +.assignee { + padding: 0.6rem; + width: auto; + display: flex; + gap: 0.6rem; + flex-direction: row; + align-items: center; +} + +.assigneeBody { + display: flex; + flex-wrap: wrap; + gap: 1rem; +} + +.delete { + padding: 0; +} + +.description { + max-height: fit-content; +} + +.description > p { + word-break: break-all; +} + +.buttons { + display: flex; + gap: 1rem; + justify-content: flex-end; + flex-wrap: wrap; +} diff --git a/frontend/components/ProjectCard/ProjectCard.tsx b/frontend/components/ProjectCard/ProjectCard.tsx new file mode 100644 index 00000000..f1ab66cb --- /dev/null +++ b/frontend/components/ProjectCard/ProjectCard.tsx @@ -0,0 +1,338 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useRouter } from "next/router"; +import { Contract, NotificationType, Project, Student } from "../../types"; +import styles from "./ProjectCard.module.css"; +import { Label } from "../Labels/Label"; +import { ProjectRole } from "../Labels/ProjectRole"; +import { useDrop } from "react-dnd"; +import SessionContext from "../../contexts/sessionProvider"; +import { NotificationContext } from "../../contexts/notificationProvider"; +import { Modal } from "../Modal/Modal"; +import { useSockets } from "../../contexts/socketProvider"; +import { defaultLoginUser } from "../../defaultLoginUser"; + +export const ProjectCard: React.FC<{ + project: Project; + updateProject: () => void; +}> = ({ project, updateProject }) => { + const router = useRouter(); + const [roleMap, setRoleMap] = useState<{ [K: string]: number }>({}); + const { getSession } = useContext(SessionContext); + const { notify } = useContext(NotificationContext); + const [showModal, setShowModal] = useState(false); + const [droppedStudent, setDroppedStudent] = useState(); + const [showDeleteModal, setShowDeleteModal] = useState(false); + const { socket } = useSockets(); + + const postAssign = async (student: Student, role: string) => { + if (student === null || student.student === null) return; + setShowModal(false); + const { sessionKey } = getSession + ? await getSession() + : { sessionKey: "" }; + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/project/${project.id}/assignee`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `auth/osoc2 ${sessionKey}`, + }, + body: JSON.stringify({ + studentId: student.student.student_id, + role: role, + jobApplicationId: student.jobApplication.job_application_id, + }), + } + ) + .then((response) => response.json()) + .catch((err) => console.log(err)); + if (response !== undefined && response.success) { + updateProject(); + if (notify) { + notify( + `Successfully assigned ${student.student.person.name} to ${project.name}`, + NotificationType.SUCCESS, + 2000 + ); + } + socket.emit("projectModified", project.id); + } else if (response !== undefined && !response.success) { + if (notify) { + notify( + `Could not assign ${student.student.person.name} to ${project.name}: + ${response.reason}`, + NotificationType.ERROR, + 3000 + ); + } + } + }; + + const dropStudent = async (item: unknown) => { + const student: Student = item as Student; + setShowModal(true); + setDroppedStudent(student); + }; + + const removeStudent = async (contract: Contract) => { + if (contract.student === null || contract.student.student === null) + return; + const { sessionKey } = getSession + ? await getSession() + : { sessionKey: "" }; + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/project/${project.id}/assignee`, + { + method: "DELETE", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `auth/osoc2 ${sessionKey}`, + }, + body: JSON.stringify({ + student: contract.student.student.student_id, + }), + } + ) + .then((response) => response.json()) + .catch((err) => console.log(err)); + if (response !== undefined && response.success) { + updateProject(); + if (notify) { + notify( + `Successfully removed ${contract.student.student.person.name} from ${project.name}`, + NotificationType.SUCCESS, + 2000 + ); + } + socket.emit("projectModified", project.id); + } else if (response !== undefined && !response.success) { + if (notify) { + notify( + `Could not remove ${contract.student.student.person.name} from ${project.name}: + ${response.reason}`, + NotificationType.ERROR, + 3000 + ); + } + } + }; + + const deleteProject = async () => { + const { sessionKey } = getSession + ? await getSession() + : { sessionKey: "" }; + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/project/${project.id}`, + { + method: "DELETE", + headers: { + Authorization: `auth/osoc2 ${sessionKey}`, + }, + } + ) + .then((response) => response.json()) + .catch((err) => console.log(err)); + if (response !== undefined && response.success) { + updateProject(); + if (notify) { + socket.emit("projectDeleted"); + notify( + `Project '${project.name}' successfully deleted!`, + NotificationType.SUCCESS, + 3000 + ); + } + } else if (response !== undefined && !response.success) { + if (notify) { + notify( + `Could not delete project ${project.name}: + ${response.reason}`, + NotificationType.ERROR, + 3000 + ); + } + } + }; + + const toggleDeleteModal = () => { + setShowDeleteModal(true); + }; + + const [{ isOver }, drop] = useDrop(() => ({ + // The type (or types) to accept - strings or symbols + accept: "Student", + // Props to collect + collect: (monitor) => ({ + isOver: monitor.isOver(), + canDrop: monitor.canDrop(), + }), + drop: (item) => { + dropStudent(item).then(); + }, + })); + + const calculateRoleMap = () => { + const map: { [K: string]: number } = {}; + for (const contract of project.contracts) { + if ( + contract.student !== null && + contract.student.student !== null + ) { + map[contract.project_role.role.name] = + (map[contract.project_role.role.name] || 0) + 1; + } + } + setRoleMap(map); + }; + + useEffect(() => { + calculateRoleMap(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [project]); + + const formatDate = (date: string) => { + const dateParts = date.split(" "); + return `${dateParts[2]} ${dateParts[1]} ${dateParts[3]}`; + }; + + return ( +
    + setShowDeleteModal(false)} + visible={showDeleteModal} + title={`Delete Project ${project.name}`} + > +

    + You are about to delete a project! Deleting a project will + result in data loss. Are you certain that you wish to delete + project {project.name}? +

    + +
    + setShowModal(false)} + title="Assign Student" + visible={showModal} + > +

    + Choose one of the following roles you want to assign the + student to: +

    + {project.roles.map((role, index) => { + return ( + + ); + })} +
    +
    +
    +
    +

    {project.name}

    +

    + {formatDate(project.start_date)} -{" "} + {formatDate(project.end_date)} +

    +
    +

    {project.partner}

    +
    + {project.coaches.map((coach) => { + return ( +
    +
    +
    + {project.roles.map((role) => { + return ( + + ); + })} +
    +
    + +
    +

    Assignees

    +
    + {project.contracts.map((contract) => { + if ( + contract.student === null || + contract.student.student === null + ) + return null; + if (contract.login_user === null) { + contract.login_user = defaultLoginUser; + } + return ( +
    +
    +

    + {contract.student.student.person.name} +

    +
    +
    +
    +
    + ); + })} +
    +
    + +
    +

    Project Description

    +

    {project.description}

    +
    + +
    + + +
    +
    + ); +}; diff --git a/frontend/components/Projects/Projects.module.scss b/frontend/components/Projects/Projects.module.scss new file mode 100644 index 00000000..8027c53b --- /dev/null +++ b/frontend/components/Projects/Projects.module.scss @@ -0,0 +1,46 @@ +.projects { + flex-direction: column; + gap: 2rem; + max-width: 60rem; +} + +/* The style for the list of projects */ +.projectCards { + display: flex; + flex-direction: column; + width: 100%; + gap: 1.5rem; + max-height: 75rem; + overflow-y: scroll; + padding-block: 4rem; + padding-inline: 2rem; + align-items: flex-start; +} + +@media (max-width: 800px) { + .projectCards { + gap: 1rem !important; + } + .projectCards.limited { + display: flex; + flex-direction: column; + + /* Scroll horizontal on small screens to still show the project overview not too far down */ + .projectCards { + flex-direction: row; + overflow-y: hidden; + overflow-x: scroll; + padding-block: 1rem; + } + } +} + +/* The actual card as a container */ +.card { + box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.5); + border-radius: 0.5rem; + display: flex; + flex-direction: column; + cursor: pointer; + width: 100%; +} diff --git a/frontend/components/Projects/Projects.tsx b/frontend/components/Projects/Projects.tsx new file mode 100644 index 00000000..97851f3d --- /dev/null +++ b/frontend/components/Projects/Projects.tsx @@ -0,0 +1,270 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useRouter } from "next/router"; +import SessionContext from "../../contexts/sessionProvider"; +import { Pagination, Project, ProjectFilterParams, Sort } from "../../types"; +import { ProjectCard } from "../ProjectCard/ProjectCard"; +import styles from "./Projects.module.scss"; +import scrollStyles from "../ScrollView.module.scss"; +import { ProjectFilter } from "../Filters/ProjectFilter"; +import { Paginator } from "../Paginator/Paginator"; +import { useSockets } from "../../contexts/socketProvider"; + +/** + * Projects page with project filter included + * @constructor + */ +export const Projects: React.FC = () => { + const router = useRouter(); + const { socket } = useSockets(); + const { getSession } = useContext(SessionContext); + const [projects, setProjects] = useState([]); + + const [params, setParams] = useState(); + const [pagination, setPagination] = useState({ + page: 0, + count: 0, + }); + + // 5 projects per page + const pageSize = 5; + + const [loading, isLoading] = useState(false); + + /** + * the code in the return value is executed when leaving the page. This will remove the listeners + */ + useEffect(() => { + return () => { + socket.off("projectWasCreatedOrDeleted"); + socket.off("projectWasModified"); + socket.off("studentWasDeleted"); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + // remove earlier listeners + socket.off("projectWasCreatedOrDeleted"); + socket.off("projectWasModified"); + socket.off("studentWasDeleted"); + + // add the new listeners + socket.on("projectWasCreatedOrDeleted", () => { + if (params !== undefined) { + filterAutomatic(params).then(); + } + }); + socket.on("projectWasModified", (projectId: number) => { + if (params !== undefined) { + for (const project of projects) { + if (project.id === projectId) { + filterAutomatic(params).then(); + break; + } + } + } + }); + socket.on("studentWasDeleted", (studentId: number) => { + if (params !== undefined) { + for (const project of projects) { + for (const contract of project.contracts) { + if ( + contract.student?.student.student_id === studentId + ) { + filterAutomatic(params).then(); + break; + } + } + } + } + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [socket, params, pagination]); + + /** + * Called by the studentfilter to filter + * Resets the pagination + * @param params + */ + const filterManual = async (params: ProjectFilterParams) => { + setParams(params); + search(params, 0).then(); + }; + + /** + * Called by the studentfilter to filter when a websocket event is received. We need to keep track of the current page! + * @param params + */ + const filterAutomatic = async (params: ProjectFilterParams) => { + setParams(params); + // get the current page + const currentPageStr = new URLSearchParams(window.location.search).get( + "currentPageProject" + ); + const currentPageInt = + currentPageStr !== null && new RegExp("[0-9]+").test(currentPageStr) // check if the argument only exists out of numbers + ? Number(currentPageStr) + : 0; + setPagination({ + page: currentPageInt, + count: 0, //TODO: what value should this be? I thought this would have to be currentPageInt * pageSize + 1 + }); + search(params, currentPageInt).then(); + }; + + /** + * Search function that uses the current pagination + * @param params + * @param page + */ + const search = async (params: ProjectFilterParams, page: number) => { + if (loading) return; + + const scrollPosition = window.scrollY; + + isLoading(true); + + const filters = []; + + if (params.nameFilter !== "") { + filters.push(`projectNameFilter=${params.nameFilter}`); + } + if (params.projectNameSort !== Sort.NONE) { + filters.push(`projectNameSort=${params.projectNameSort}`); + } + if (params.clientFilter !== "") { + filters.push(`clientNameFilter=${params.clientFilter}`); + } + if (params.clientSort !== Sort.NONE) { + filters.push(`clientNameSort=${params.clientSort}`); + } + if (params.fullyAssigned) { + filters.push(`fullyAssignedFilter=${params.fullyAssigned}`); + } + if (params.osocYear !== "") { + filters.push(`osocYear=${params.osocYear}`); + } + + filters.push(`currentPage=${page}`); + filters.push(`pageSize=${pageSize}`); + + const query = filters.length > 0 ? `?${filters.join("&")}` : ""; + const { sessionKey } = getSession + ? await getSession() + : { sessionKey: "" }; + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/project/filter${query}`, + { + method: "GET", + headers: { + Authorization: `auth/osoc2 ${sessionKey}`, + "Content-Type": "application/json", + Accept: "application/json", + }, + } + ) + .then((response) => response.json()) + .catch((err) => { + console.log(err); + }); + + if (response !== undefined && response.success) { + setProjects(response.data); + setPagination(response.pagination); + } + isLoading(false); + + // these are the search parameters we just sent + const newSearchParams = new URLSearchParams(query); + + // set the page filter unique for the student to keep track of it in the frontend + newSearchParams.delete("currentPage"); + newSearchParams.delete("pageSize"); + newSearchParams.set("currentPageProject", page.toString()); + newSearchParams.set("pageSizeProject", pageSize.toString()); + + // we have to change the parameter name of osocYear to osocYearProject to prevent conflicts with the selected year for the student filter + const setYear = newSearchParams.get("osocYear"); + if (setYear !== null) { + newSearchParams.set("osocYearProject", setYear); + } + + // get the current active search parameters, we'll update this value + const updatedSearchParams = new URLSearchParams(window.location.search); + // overwrite the values that are present in the new and old parameters + newSearchParams.forEach((value, key) => { + updatedSearchParams.set(key, value); + }); + + const projectFilterKeys = new Set([ + "projectYearFilter", + "projectNameSort", + "projectNameFilter", + "clientNameSort", + "clientNameFilter", + "fullyAssignedFilter", + ]); + // delete the values that are not present anymore in the new filter and are project related + updatedSearchParams.forEach((_, key) => { + if (!newSearchParams.has(key) && projectFilterKeys.has(key)) { + updatedSearchParams.delete(key); + } + }); + + router + .push( + `${window.location.pathname}?${updatedSearchParams.toString()}` + ) + .then(() => window.scrollTo(0, scrollPosition)); + }; + + const navigator = (page: number) => { + if (params !== undefined) { + search(params, page).then(); + } + }; + + return ( +
    + + +
    +
    +
    + {projects.map((project) => { + return ( +
    + { + if (params !== undefined) { + search( + params, + pagination.page + ).then(); + } + }} + project={project} + /> +
    + ); + })} +
    +
    +
    + +
    + ); +}; diff --git a/frontend/components/ScrollView.module.scss b/frontend/components/ScrollView.module.scss new file mode 100644 index 00000000..10690fed --- /dev/null +++ b/frontend/components/ScrollView.module.scss @@ -0,0 +1,46 @@ +.scrollView { + position: relative; + z-index: 0; +} + +@media (max-width: 800px) { + .scrollView { + display: flex; + } + + .topShadowCaster, .bottomShadowCaster { + margin-inline: auto; + width: 3rem !important; + height: 100%; + z-index: 1; + position: absolute; + } + + .topShadowCaster { + margin-left: -1rem !important; + background: linear-gradient(90deg, var(--neutral-100), transparent) !important; + } + .bottomShadowCaster { + background: linear-gradient(-90deg, var(--neutral-100), transparent) !important; + margin-top: 0 !important; + margin-right: -1rem !important; + right: 0; + top: 0 !important; + } +} + +.topShadowCaster, .bottomShadowCaster { + margin-inline: auto; + min-height: 3rem; + width: 100%; + z-index: 1; + position: absolute; +} +.topShadowCaster { + background: linear-gradient(180deg, var(--neutral-100), transparent); +} +.bottomShadowCaster { + background: linear-gradient(0deg, var(--neutral-100), transparent); + margin-top: -2rem; + top: 100%; +} diff --git a/frontend/components/Settings/Settings.tsx b/frontend/components/Settings/Settings.tsx index eb26f636..d3f50abc 100644 --- a/frontend/components/Settings/Settings.tsx +++ b/frontend/components/Settings/Settings.tsx @@ -1,9 +1,10 @@ import React, { SyntheticEvent, useContext, useState } from "react"; -import { LoginUser } from "../../types"; +import { LoginUser, NotificationType } from "../../types"; import SessionContext from "../../contexts/sessionProvider"; -import crypto from "crypto"; -import styles from "../../styles/login.module.scss"; +import styles from "../../pages/login/login.module.scss"; import isStrongPassword from "validator/lib/isStrongPassword"; +import { NotificationContext } from "../../contexts/notificationProvider"; +import { defaultLoginUser } from "../../defaultLoginUser"; export const Settings: React.FC<{ person: LoginUser; @@ -12,12 +13,17 @@ export const Settings: React.FC<{ const [newName, setNewName] = useState(""); const [currPassword, setCurrPassword] = useState(""); const [newPassword, setNewPassword] = useState(""); + const [retypePassword, setRetypePassword] = useState(""); const [currPasswordError, setCurrPasswordError] = useState(""); const [newPasswordError, setNewPasswordError] = useState(""); const [newPasswordScore, setNewPasswordScore] = useState(0); const [applyError, setApplyError] = useState(""); const { getSession, setSessionKey } = useContext(SessionContext); + const { notify } = useContext(NotificationContext); + if (person === null) { + person = defaultLoginUser; + } /** * Gets called everytime the new password input field's value changes * Calculates the password score and set the corresponding error messages @@ -32,6 +38,10 @@ export const Settings: React.FC<{ setNewPassword(password); }; + const updateRetypePass = (password: string) => { + setRetypePassword(password); + }; + /** * Converts the register password strength score to a textual representation */ @@ -79,6 +89,9 @@ export const Settings: React.FC<{ } else if (currPassword !== "" && newPasswordScore < 20) { setNewPasswordError("Please provide a secure enough password"); error = true; + } else if (newPassword !== retypePassword) { + setNewPasswordError("Passwords do not match"); + error = true; } else { setNewPasswordError(""); } @@ -94,17 +107,6 @@ export const Settings: React.FC<{ setApplyError(""); } - const { sessionKey } = - getSession != undefined ? await getSession() : { sessionKey: "" }; - const encryptedOldPassword = crypto - .createHash("sha256") - .update(currPassword) - .digest("hex"); - const encryptedNewPassword = crypto - .createHash("sha256") - .update(newPassword) - .digest("hex"); - // We dynamically build the body const body: Record = {}; if (newName !== "") { @@ -113,12 +115,15 @@ export const Settings: React.FC<{ if (currPassword !== "" && newPassword !== "") { body.pass = { - oldpass: encryptedOldPassword, - newpass: encryptedNewPassword, + oldpass: currPassword, + newpass: newPassword, }; } if (body !== {}) { + const { sessionKey } = getSession + ? await getSession() + : { sessionKey: "" }; const response = await fetch( `${process.env.NEXT_PUBLIC_API_URL}/user/self`, { @@ -132,25 +137,32 @@ export const Settings: React.FC<{ } ) .then((response) => response.json()) - .catch((err) => { + .catch(() => { setApplyError( "Something went wrong while trying to execute your request." ); - console.log(err); }); - console.log(response); - if (response !== undefined) { - if (response.success) { - if (setSessionKey) { - setSessionKey(response.sessionkey); - } - fetchUser(); - // TODO notify succes - } else { - setApplyError( - `Failed to apply changes. Please check all fields. ${response.reason}` + if (response && response.success) { + if (setSessionKey) { + setSessionKey(response.sessionkey); + } + await fetchUser(); + if (notify) { + notify( + "Your credentials are successfully changed", + NotificationType.SUCCESS, + 2000 ); } + } else if (response && !response.success && notify) { + setApplyError( + `Failed to apply changes. Please check all fields. ${response.reason}` + ); + notify( + "Something went wrong:" + response.reason, + NotificationType.ERROR, + 2000 + ); } } }; @@ -158,22 +170,30 @@ export const Settings: React.FC<{ return (
    -