diff options
| author | Max Nanis | 2026-09-13 19:03:55 +0000 |
|---|---|---|
| committer | Max Nanis | 2026-09-13 19:03:55 +0000 |
| commit | 8fbe8d439b418796932aaa88297e006c714e4d13 (patch) | |
| tree | 6c800476edc1e771fc570b559d483df8d59d4324 /jb-ui/src/models/profilingUtils.ts | |
| parent | 12f6fee851b68e86af658dfa17e4a0daed457dd1 (diff) | |
| parent | 2c94f248d2438071a918fa9a30bf114ef9aa29b4 (diff) | |
| download | amt-jb-8fbe8d439b418796932aaa88297e006c714e4d13.tar.gz amt-jb-8fbe8d439b418796932aaa88297e006c714e4d13.zip | |
Merges pull request #3
Off of Amazon!!!
Diffstat (limited to 'jb-ui/src/models/profilingUtils.ts')
| -rw-r--r-- | jb-ui/src/models/profilingUtils.ts | 309 |
1 files changed, 163 insertions, 146 deletions
diff --git a/jb-ui/src/models/profilingUtils.ts b/jb-ui/src/models/profilingUtils.ts index 104a5bb..a3ef7d2 100644 --- a/jb-ui/src/models/profilingUtils.ts +++ b/jb-ui/src/models/profilingUtils.ts @@ -1,29 +1,36 @@ -import { PatternValidation, UpkQuestionConfigurationMC, UpkQuestionConfigurationTE } from "@/api_fsb"; +import { + PatternValidation, + UpkQuestionConfigurationMC, + UpkQuestionConfigurationTE, +} from "@/api_fsb"; import { assert } from "@/lib/utils"; -import { ProfileQuestion, ValidationError } from '@/models/profilingQuestionsSlice'; -import { Filter } from 'bad-words'; +import { + ProfileQuestion, + ValidationError, +} from "@/models/profilingQuestionsSlice"; +import { Filter } from "bad-words"; const filter = new Filter(); export const questionUtils = { - - assignValidationState: (question: ProfileQuestion): ProfileQuestion => { - /* This function performs validation on the question's current answers and + assignValidationState: (question: ProfileQuestion): ProfileQuestion => { + /* This function performs validation on the question's current answers and assigns any error messages to question._metadata.error_msg. If the question is MC, validate: */ - const errors = question._validation.errors ?? [] + const errors = question._validation.errors ?? []; - question._validation.isComplete = errors.length === 0 - question._validation.isValid = errors.filter(e => e.severity === 'error').length === 0 + question._validation.isComplete = errors.length === 0; + question._validation.isValid = + errors.filter((e) => e.severity === "error").length === 0; - return question; - }, + return question; + }, - validate: (question: ProfileQuestion): ProfileQuestion => { - /* If the question is MC, validate: + validate: (question: ProfileQuestion): ProfileQuestion => { + /* If the question is MC, validate: - validate selector SA vs MA (1 selected vs >1 selected) - the answers match actual codes in the choices @@ -35,121 +42,132 @@ export const questionUtils = { - validation.patterns */ - assert(question.question_id, "Question must have question_id") - // assert(question.configuration, "Question must have configuration") - const answers = question._metadata.answers ?? [] - - // Declare it here, and they we'll reassign any specific - // configuration types based on the question type. - - // Start fresh without any error messages before validating - const errors: ValidationError[] = [] - - switch (question.question_type) { - case "TE": - - answers.length === 0 && errors.push({ - path: `question_id:${question.question_id}`, - message: "No answer provided", - severity: "warning", - } as ValidationError) - - answers.length > 1 && errors.push({ - path: `question_id:${question.question_id}`, - message: "Only one answer allowed", - severity: "error", - } as ValidationError) - - let answer_text: string = answers[0] - - const te_config = question.configuration as UpkQuestionConfigurationTE - const min_length = te_config.min_length ?? 0 - const max_length = te_config.max_length ?? 100_000 - - answer_text.length < min_length && errors.push({ - path: `question_id:${question.question_id}`, - message: "Answer shorter than allowed", - severity: "warning", - } as ValidationError) - - answer_text.length > max_length && errors.push({ - path: `question_id:${question.question_id}`, - message: "Answer longer than allowed", - severity: "error", - } as ValidationError) - - filter.isProfane(answer_text) && errors.push({ - path: `question_id:${question.question_id}`, - message: "Answer has inappropriate content", - severity: "error", - } as ValidationError) - - const patterns: PatternValidation[] = (question.validation ?? {})["patterns"] ?? [] - patterns.forEach((pv) => { - let re = new RegExp(pv.pattern) - answer_text.search(re) == -1 && errors.push({ - path: `question_id:${question.question_id}`, - message: pv.message, - severity: "error", - } as ValidationError) - - }) - - break; - - case "MC": - - answers.length === 0 && errors.push({ - path: `question_id:${question.question_id}`, - message: "Multiple Choice question with no selected answers", - severity: "warning", - } as ValidationError) - - const choice_codes: string[] = question.choices?.map((c) => c.choice_id) ?? []; - - const mc_config = (question.configuration ?? {}) as UpkQuestionConfigurationMC - const max_select = mc_config.max_select ?? choice_codes.length - - switch (question.selector) { - case "SA": - answers.length > 1 && errors.push({ - path: `question_id:${question.question_id}`, - message: "Single Answer MC question with >1 selected answers", - severity: "error", - } as ValidationError) - - break; - - case "MA": - answers.length > max_select && errors.push({ - path: `question_id:${question.question_id}`, - message: "More options selected than allowed", - severity: "error", - } as ValidationError) - - answers.length === max_select && errors.push({ - path: `question_id:${question.question_id}`, - message: "Selected all the options", - severity: "error", - } as ValidationError) - - break; - } - - // Now validate Multiple Choice answers regardless of if - // they're Single Answer (SA) or Multiple Answer (MA) - !answers.every(item => choice_codes.includes(item)) && errors.push({ - path: `question_id:${question.question_id}`, - message: "Invalid options selected", - severity: "error", - }) - - // const max_select: number = question.configuration?.max_select ?? choice_codes.length - // if (answer.values.length > max_select) { - // answer.error_msg = "More options selected than allowed" - // } - - /* + assert(question.question_id, "Question must have question_id"); + // assert(question.configuration, "Question must have configuration") + const answers = question._metadata.answers ?? []; + + // Declare it here, and they we'll reassign any specific + // configuration types based on the question type. + + // Start fresh without any error messages before validating + const errors: ValidationError[] = []; + + switch (question.question_type) { + case "TE": + answers.length === 0 && + errors.push({ + path: `question_id:${question.question_id}`, + message: "No answer provided", + severity: "warning", + } as ValidationError); + + answers.length > 1 && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Only one answer allowed", + severity: "error", + } as ValidationError); + + let answer_text: string = answers[0]; + + const te_config = question.configuration as UpkQuestionConfigurationTE; + const min_length = te_config.min_length ?? 0; + const max_length = te_config.max_length ?? 100_000; + + answer_text.length < min_length && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Answer shorter than allowed", + severity: "warning", + } as ValidationError); + + answer_text.length > max_length && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Answer longer than allowed", + severity: "error", + } as ValidationError); + + filter.isProfane(answer_text) && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Answer has inappropriate content", + severity: "error", + } as ValidationError); + + const patterns: PatternValidation[] = + (question.validation ?? {})["patterns"] ?? []; + patterns.forEach((pv) => { + let re = new RegExp(pv.pattern); + answer_text.search(re) == -1 && + errors.push({ + path: `question_id:${question.question_id}`, + message: pv.message, + severity: "error", + } as ValidationError); + }); + + break; + + case "MC": + answers.length === 0 && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Multiple Choice question with no selected answers", + severity: "warning", + } as ValidationError); + + const choice_codes: string[] = + question.choices?.map((c) => c.choice_id) ?? []; + + const mc_config = (question.configuration ?? + {}) as UpkQuestionConfigurationMC; + const max_select = mc_config.max_select ?? choice_codes.length; + + switch (question.selector) { + case "SA": + answers.length > 1 && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Single Answer MC question with >1 selected answers", + severity: "error", + } as ValidationError); + + break; + + case "MA": + answers.length > max_select && + errors.push({ + path: `question_id:${question.question_id}`, + message: "More options selected than allowed", + severity: "error", + } as ValidationError); + + answers.length === max_select && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Selected all the options", + severity: "error", + } as ValidationError); + + break; + } + + // Now validate Multiple Choice answers regardless of if + // they're Single Answer (SA) or Multiple Answer (MA) + !answers.every((item) => choice_codes.includes(item)) && + errors.push({ + path: `question_id:${question.question_id}`, + message: "Invalid options selected", + severity: "error", + }); + + // const max_select: number = question.configuration?.max_select ?? choice_codes.length + // if (answer.values.length > max_select) { + // answer.error_msg = "More options selected than allowed" + // } + + /* exclusive_choice = next((x for x in question["choices"] if x.get("exclusive")), None) if exclusive_choice: exclusive_choice_id = exclusive_choice["choice_id"] @@ -157,21 +175,20 @@ export const questionUtils = { exclusive_choice_id not in answer, "Invalid exclusive selection" */ - break; - - default: - errors.push({ - path: `question_id:${question.question_id}`, - message: "Incorrect Question Type provided", - severity: "error", - } as ValidationError) - } - - // Assign the errors back to the question's _validation field and - // then return the question - // TODO: does this edit in place, maybe I don't need to return it - question._validation.errors = errors - return question; - }, - -};
\ No newline at end of file + break; + + default: + errors.push({ + path: `question_id:${question.question_id}`, + message: "Incorrect Question Type provided", + severity: "error", + } as ValidationError); + } + + // Assign the errors back to the question's _validation field and + // then return the question + // TODO: does this edit in place, maybe I don't need to return it + question._validation.errors = errors; + return question; + }, +}; |
