fixture(); $errors = qdb_validate_app_submit_payload($pdo, $f->questionnaireId, [], [], [], [], []); qdb_discard($tmpDb, $lockFp); $this->assertNotEmpty($errors); $this->assertSame('ANSWERS_REQUIRED', $errors[0]['code']); } public function testUnknownQuestionRejected(): void { require_once dirname(__DIR__, 2) . '/lib/app_submit_validate.php'; [$pdo, $tmpDb, $lockFp] = qdb_open(false); $f = $this->fixture(); $errors = qdb_validate_app_submit_payload( $pdo, $f->questionnaireId, [['questionID' => 'nope', 'answerOptionKey' => 'x']], [], [], [], [] ); qdb_discard($tmpDb, $lockFp); $this->assertSame('UNKNOWN_QUESTION', $errors[0]['code'] ?? ''); } public function testUnknownQuestionAllowedInLegacyManifest(): void { require_once dirname(__DIR__, 2) . '/lib/app_submit_validate.php'; require_once dirname(__DIR__, 2) . '/lib/questionnaire_structure.php'; [$pdo, $tmpDb, $lockFp] = qdb_open(false); $f = $this->fixture(); $manifest = qdb_build_structure_manifest($pdo, $f->questionnaireId, true); $maps = qdb_submit_maps_from_manifest($pdo, $f->questionnaireId, $manifest); $errors = qdb_validate_app_submit_payload( $pdo, $f->questionnaireId, [['questionID' => $f->questionShortId, 'answerOptionKey' => 'yes']], $maps['shortIdMap'], $maps['shortIdToType'], $maps['symptomParentMap'], $maps['optionMap'], $manifest ); qdb_discard($tmpDb, $lockFp); $this->assertSame([], $errors); } public function testValidSingleChoiceWithOptionKeyPasses(): void { require_once dirname(__DIR__, 2) . '/lib/app_submit_validate.php'; [$pdo, $tmpDb, $lockFp] = qdb_open(false); $f = $this->fixture(); $shortMap = [$f->questionShortId => $f->questionId]; $typeMap = [$f->questionShortId => 'single_choice_question']; $optMap = [ $f->questionId => [ 'yes' => ['answerOptionID' => $f->optionId, 'points' => 0], ], ]; $errors = qdb_validate_app_submit_payload( $pdo, $f->questionnaireId, [['questionID' => $f->questionShortId, 'answerOptionKey' => 'yes']], $shortMap, $typeMap, [], $optMap, ); qdb_discard($tmpDb, $lockFp); $this->assertSame([], $errors); } public function testMultiCheckRequiresSelection(): void { require_once dirname(__DIR__, 2) . '/lib/app_submit_validate.php'; [$pdo, $tmpDb, $lockFp] = qdb_open(false); $f = $this->fixture(); $shortMap = [$f->multiCheckShortId => $f->multiCheckQuestionId]; $typeMap = [$f->multiCheckShortId => 'multi_check_box_question']; $errors = qdb_validate_app_submit_payload( $pdo, $f->questionnaireId, [['questionID' => $f->multiCheckShortId, 'freeTextValue' => '']], $shortMap, $typeMap, [], [], ); qdb_discard($tmpDb, $lockFp); $this->assertSame('EMPTY_ANSWER', $errors[0]['code'] ?? ''); } public function testInvalidOptionKeyRejected(): void { require_once dirname(__DIR__, 2) . '/lib/app_submit_validate.php'; [$pdo, $tmpDb, $lockFp] = qdb_open(false); $f = $this->fixture(); $shortMap = [$f->questionShortId => $f->questionId]; $typeMap = [$f->questionShortId => 'single_choice_question']; $optMap = [ $f->questionId => [ 'yes' => ['answerOptionID' => $f->optionId, 'points' => 0], ], ]; $errors = qdb_validate_app_submit_payload( $pdo, $f->questionnaireId, [['questionID' => $f->questionShortId, 'answerOptionKey' => 'No']], $shortMap, $typeMap, [], $optMap, ); qdb_discard($tmpDb, $lockFp); $this->assertSame('INVALID_OPTION', $errors[0]['code'] ?? ''); } }