From fee7ae4ee5d88057294faa967b986ad59858b890 Mon Sep 17 00:00:00 2001 From: Rello Date: Mon, 1 Sep 2025 23:28:27 +0700 Subject: [PATCH] Fix numeric drilldown sorting --- CHANGELOG.md | 1 + lib/Controller/DatasourceController.php | 4 +- tests/Controller/DatasourceControllerTest.php | 50 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/Controller/DatasourceControllerTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d00b2a1b..0591f9d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Fix PHP 8.4 deprecation warnings #534 @[robertoschwald](https://github.com/robertoschwald) - date formatting on all rows - fix double report execution after wizard close +- correct drilldown aggregation for numeric dimension indices ## 5.8.0 - 2025-07-29 ### Added diff --git a/lib/Controller/DatasourceController.php b/lib/Controller/DatasourceController.php index 93dc3e49..808a275c 100644 --- a/lib/Controller/DatasourceController.php +++ b/lib/Controller/DatasourceController.php @@ -302,8 +302,8 @@ private function aggregateData($data, $filter) { $options = json_decode($filter, true); if (isset($options['drilldown'])) { // Sort the indices in descending order - $sortedIndices = array_keys($options['drilldown']); - rsort($sortedIndices); + $sortedIndices = array_keys($options['drilldown']); + rsort($sortedIndices, SORT_NUMERIC); foreach ($sortedIndices as $removeIndex) { $aggregatedData = []; diff --git a/tests/Controller/DatasourceControllerTest.php b/tests/Controller/DatasourceControllerTest.php new file mode 100644 index 00000000..147ee223 --- /dev/null +++ b/tests/Controller/DatasourceControllerTest.php @@ -0,0 +1,50 @@ +createMock(\OCP\IRequest::class), + $this->createMock(\Psr\Log\LoggerInterface::class), + $this->createMock(\OCA\Analytics\Datasource\Github::class), + $this->createMock(\OCA\Analytics\Datasource\LocalCsv::class), + $this->createMock(\OCA\Analytics\Datasource\Regex::class), + $this->createMock(\OCA\Analytics\Datasource\ExternalJson::class), + $this->createMock(\OCA\Analytics\Datasource\LocalJson::class), + $this->createMock(\OCA\Analytics\Datasource\ExternalCsv::class), + $this->createMock(\OCA\Analytics\Datasource\LocalSpreadsheet::class), + new FakeL10N(), + $this->createMock(\OCP\EventDispatcher\IEventDispatcher::class), + $this->createMock(\OCP\IAppConfig::class) + ); + + $header = []; + $row1 = []; + $row2 = []; + for ($i = 0; $i <= 10; $i++) { + $header[] = 'col' . $i; + $row1[] = 'r1c' . $i; + $row2[] = 'r2c' . $i; + } + $header[] = 'Value'; + $row1[] = 1; + $row2[] = 2; + $data = ['header' => $header, 'data' => [$row1, $row2]]; + + $filter = json_encode(['drilldown' => ['2' => true, '10' => true]]); + $reflection = new \ReflectionClass(DatasourceController::class); + $method = $reflection->getMethod('aggregateData'); + $method->setAccessible(true); + $result = $method->invoke($controller, $data, $filter); + + $this->assertSame('Value', end($result['header'])); + $this->assertNotContains('col2', $result['header']); + $this->assertNotContains('col10', $result['header']); + $this->assertCount(10, $result['header']); + } +}