assertEqualsCanonicalizing(['a', 'b'], $decoded); } public function testDecodeMultiCheckFromJsonArray(): void { $this->assertSame(['x', 'y'], qdb_decode_multi_check_values('["x","y"]')); } public function testDecodeMultiCheckFromCommaSeparated(): void { $this->assertSame(['one', 'two'], qdb_decode_multi_check_values('one, two')); } public function testBuildGlassSymptomJsonOmitsEmptyAndReturnsNullForNoSymptoms(): void { require_once dirname(__DIR__, 2) . '/lib/app_answers.php'; $this->assertNull(qdb_build_glass_symptom_json([])); $this->assertNull(qdb_build_glass_symptom_json(['pain' => ''])); $json = qdb_build_glass_symptom_json(['pain' => 'mild', 'fatigue' => 'severe']); $this->assertSame(['pain' => 'mild', 'fatigue' => 'severe'], json_decode((string)$json, true)); } public function testGroupAppSubmitAnswersMergesMultiCheck(): void { $answers = [ ['questionID' => 'q1', 'answerOptionKey' => 'opt_a', 'answeredAt' => 100], ['questionID' => 'q1', 'answerOptionKey' => 'opt_b', 'answeredAt' => 100], ['questionID' => 'q2', 'freeTextValue' => 'hello'], ]; $grouped = qdb_group_app_submit_answers( $answers, ['q1' => 'multi_check_box_question', 'q2' => 'text_question'], [] ); $this->assertCount(2, $grouped); $this->assertSame('q1', $grouped[0]['questionID']); $decoded = json_decode((string)$grouped[0]['freeTextValue'], true, 512, JSON_THROW_ON_ERROR); $this->assertEqualsCanonicalizing(['opt_a', 'opt_b'], $decoded); $this->assertSame('hello', $grouped[1]['freeTextValue']); } public function testGroupAppSubmitAnswersPreservesSymptomRows(): void { $answers = [ ['questionID' => 'fatigue', 'answerOptionKey' => 'moderate'], ]; $grouped = qdb_group_app_submit_answers( $answers, ['fatigue' => 'glass_scale_question'], ['fatigue' => 'glass_parent'] ); $this->assertCount(1, $grouped); $this->assertSame('moderate', $grouped[0]['answerOptionKey']); } }