From a5e20dcb68e0f3d902eb21fe47c52b1a86107386 Mon Sep 17 00:00:00 2001 From: Gabriel Jenik Date: Tue, 6 Jun 2023 13:13:06 -0300 Subject: [PATCH] Fixed issue #18814: Array question statistics fail for Remote Control (#3191) * Dev: Remote Control export statistics tests. Tests added for surveys with one single question and with multiple questions. * Dev: Remote Control export statistics tests. Asserts added to cope with error. * Dev: Remote Control export statistics tests. Echo added to check the html string returned by export statistics. * Dev: Remote Control export statistics tests. Statistics tables are now fetched depending on the question id. * Dev: Remote Control export statistics wit array questions tests. Tests added for surveys with array questions. * Fixed issue #18814: Array question statistics fail for Remote Control. Bug fixed. * Dev: Remote Control export statistics wit array questions tests. Asserts for specific questions added. * Dev: Remote Control export statistics wit array questions tests. Undefined variable bug fixed. --------- Co-authored-by: Lapiu Dev --- application/helpers/common_helper.php | 2 +- .../data/surveys/survey_statistics_three.lsa | Bin 0 -> 4455 bytes .../ExportStatisticsArrayQuestionsTest.php | 131 ++++++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 tests/data/surveys/survey_statistics_three.lsa create mode 100644 tests/unit/helpers/remotecontrol/ExportStatisticsArrayQuestionsTest.php diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index 094e0dd672b..46c0874dea7 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -1215,7 +1215,7 @@ function createCompleteSGQA($iSurveyID, $aFilters, $sLanguage) //go through all the (multiple) answers foreach ($result as $row) { - $myfield2 = $myfield . reset($row); + $myfield2 = $myfield . $row['title']; $allfields[] = $myfield2; } break; diff --git a/tests/data/surveys/survey_statistics_three.lsa b/tests/data/surveys/survey_statistics_three.lsa new file mode 100644 index 0000000000000000000000000000000000000000..31a11a191bb297aad89b2582856b2e28d4e90183 GIT binary patch literal 4455 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 V3?d}@@AJJs{nwv4^5DPQe*jzBT513Q literal 0 HcmV?d00001 diff --git a/tests/unit/helpers/remotecontrol/ExportStatisticsArrayQuestionsTest.php b/tests/unit/helpers/remotecontrol/ExportStatisticsArrayQuestionsTest.php new file mode 100644 index 00000000000..c43e566f3b9 --- /dev/null +++ b/tests/unit/helpers/remotecontrol/ExportStatisticsArrayQuestionsTest.php @@ -0,0 +1,131 @@ +setController(new DummyController('dummyid')); + } + + public function testSurveyWithOneQuestion() + { + // Import survey + $filename = self::$surveysFolder . '/survey_statistics_three.lsa'; + self::importSurvey($filename); + + $sessionKey = $this->handler->get_session_key($this->getUsername(), $this->getPassword()); + $htmlStatistics = $this->handler->export_statistics($sessionKey, self::$surveyId, 'html'); + $htmlStatistics = base64_decode($htmlStatistics); + + // Q00 + $questionData = $this->getTableData($htmlStatistics); + + // Subquestion one + + // Option one row. + $this->assertSame($questionData[0][0], 'Option one (AO01)', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[0][1], '3', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[0][2], '30.00%', 'The Percentage is incorrect for this option.'); + + // Option two row. + $this->assertSame($questionData[1][0], 'Option two (AO02)', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[1][1], '4', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[1][2], '40.00%', 'The Percentage is incorrect for this option.'); + + // No answer row. + $this->assertSame($questionData[2][0], 'No answer', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[2][1], '0', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[2][2], '0.00%', 'The Percentage is incorrect for this option.'); + + // Not completed row. + $this->assertSame($questionData[3][0], 'Not completed or Not displayed', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[3][1], '3', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[3][2], '30.00%', 'The Percentage is incorrect for this option.'); + + // A row is left empty. + $this->assertEmpty($questionData[4], 'This row should be empty.'); + + // Total row. + $this->assertSame($questionData[5][0], 'Total(gross)', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[5][1], '10', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[5][2], '100.00%', 'The Percentage is incorrect for this option.'); + + + // Subquestion two + + // Option one row. + $this->assertSame($questionData[6][0], 'Option one (AO01)', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[6][1], '4', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[6][2], '40.00%', 'The Percentage is incorrect for this option.'); + + // Option two row. + $this->assertSame($questionData[7][0], 'Option two (AO02)', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[7][1], '3', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[7][2], '30.00%', 'The Percentage is incorrect for this option.'); + + // No answer row. + $this->assertSame($questionData[8][0], 'No answer', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[8][1], '0', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[8][2], '0.00%', 'The Percentage is incorrect for this option.'); + + // Not completed row. + $this->assertSame($questionData[9][0], 'Not completed or Not displayed', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[9][1], '3', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[9][2], '30.00%', 'The Percentage is incorrect for this option.'); + + // A row is left empty. + $this->assertEmpty($questionData[10], 'This row should be empty.'); + + // Total row. + $this->assertSame($questionData[11][0], 'Total(gross)', 'The Answer text is incorrect for this option.'); + $this->assertSame($questionData[11][1], '10', 'The Count is incorrect for this option.'); + $this->assertSame($questionData[11][2], '100.00%', 'The Percentage is incorrect for this option.'); + } + + /** + * Get the statistics data from the table with the + * id specified. + */ + private function getTableData($htmlStatistics) + { + $options = array(); + + // Get the table. + $doc = new \DOMDocument(); + $doc->loadHtml($htmlStatistics); + + $tables = $doc->getElementsByTagName('table'); + + if ($tables === null) { + return $options; + } + + foreach ($tables as $table) { + $thead = $table->getElementsByTagName('thead')->item(0); + // The td tags should be identified with the opening tbody tag but it is not added by export_statistics. + $table->removeChild($thead); + + $rows = $table->getElementsByTagName('tr'); + + foreach ($rows as $rowKey => $row) { + $tds = $row->getElementsByTagName('td'); + $option = array(); + + foreach ($tds as $td) { + $option[] = trim($td->nodeValue); + } + + $options[] = $option; + } + } + + return $options; + } +}