diff --git a/lib/Analytics/AnalyticsDatasource.php b/lib/Analytics/AnalyticsDatasource.php index 62f520b4b4..2bf8f6e516 100644 --- a/lib/Analytics/AnalyticsDatasource.php +++ b/lib/Analytics/AnalyticsDatasource.php @@ -98,6 +98,7 @@ public function getTemplate(): array { public function readData($option): array { $questionMap = []; $answerCounts = []; + $results = []; $formId = $option['formId']; @@ -109,19 +110,17 @@ public function readData($option): array { $submissions = $this->submissionService->getSubmissions($formId); foreach ($submissions as $submission) { foreach ($submission['answers'] as $answer) { - $questionText = $questionMap[$answer['questionId']]; - $key = $questionText . '|' . $answer['text']; - if (isset($answerCounts[$key])) { - $answerCounts[$key]++; - } else { - $answerCounts[$key] = 1; + if (!isset($questionMap[$answer['questionId']])) { + continue; } + $answerCounts[$answer['questionId']][$answer['text']] = ($answerCounts[$answer['questionId']][$answer['text']] ?? 0) + 1; } } - foreach ($answerCounts as $key => $count) { - [$questionText, $text] = explode('|', $key); - $results[] = [$questionText, $text, $count]; + foreach ($answerCounts as $questionId => $counts) { + foreach ($counts as $text => $count) { + $results[] = [$questionMap[$questionId], (string)$text, $count]; + } } // Sort by questionText ascending and count descending diff --git a/tests/Unit/Analytics/AnalyticsDatasourceTest.php b/tests/Unit/Analytics/AnalyticsDatasourceTest.php index c01330a684..1598d8b187 100644 --- a/tests/Unit/Analytics/AnalyticsDatasourceTest.php +++ b/tests/Unit/Analytics/AnalyticsDatasourceTest.php @@ -123,4 +123,47 @@ public function testReadData() { $this->assertEquals($expectedData, $data); } + + public function testReadDataWithoutAnswers(): void { + $this->formsService->method('getQuestions')->willReturn([['id' => 1, 'text' => 'Question 1']]); + $this->submissionService->method('getSubmissions')->willReturn([]); + $this->l10n->method('t')->willReturnArgument(0); + + $this->assertSame([], $this->analyticsDatasource->readData(['formId' => 123])['data']); + } + + public function testReadDataSkipsAnswersOfDeletedQuestions(): void { + $this->formsService->method('getQuestions')->willReturn([['id' => 1, 'text' => 'Question 1']]); + $this->submissionService->method('getSubmissions')->willReturn([ + ['answers' => [ + ['questionId' => 1, 'text' => 'Answer 1'], + ['questionId' => 2, 'text' => 'Answer of a deleted question'], + ]], + ]); + $this->l10n->method('t')->willReturnArgument(0); + + $this->assertSame([['Question 1', 'Answer 1', 1]], $this->analyticsDatasource->readData(['formId' => 123])['data']); + } + + public function testReadDataKeepsSeparatorsAndQuestionsWithTheSameTitle(): void { + $this->formsService->method('getQuestions')->willReturn([ + ['id' => 1, 'text' => 'Pick A|B'], + ['id' => 2, 'text' => 'Comment'], + ['id' => 3, 'text' => 'Comment'], + ]); + $this->submissionService->method('getSubmissions')->willReturn([ + ['answers' => [ + ['questionId' => 1, 'text' => 'a|b'], + ['questionId' => 2, 'text' => '5'], + ['questionId' => 3, 'text' => '5'], + ]], + ]); + $this->l10n->method('t')->willReturnArgument(0); + + $this->assertSame([ + ['Comment', '5', 1], + ['Comment', '5', 1], + ['Pick A|B', 'a|b', 1], + ], $this->analyticsDatasource->readData(['formId' => 123])['data']); + } }