From c0c8fee6bedcea51f1674ecbbd37a9504d493d2d Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Fri, 24 Jul 2026 15:36:51 +0200 Subject: [PATCH] default time entry type filter to work for legacy reports --- app/Service/Dto/ReportPropertiesDto.php | 8 +- .../Service/Dto/ReportPropertiesDtoTest.php | 91 +++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Service/Dto/ReportPropertiesDtoTest.php diff --git a/app/Service/Dto/ReportPropertiesDto.php b/app/Service/Dto/ReportPropertiesDto.php index bfb2583f..dc232db8 100644 --- a/app/Service/Dto/ReportPropertiesDto.php +++ b/app/Service/Dto/ReportPropertiesDto.php @@ -132,8 +132,12 @@ class ReportPropertiesDto implements Castable $dto->roundingType = isset($data->roundingType) ? TimeEntryRoundingType::from($data->roundingType) : null; // Note: roundingMinutes was added later so it is possible that the value is missing in persisted reports in the DB $dto->roundingMinutes = isset($data->roundingMinutes) ? (int) $data->roundingMinutes : null; - // Note: timeEntryType was added later so it is possible that the value is missing in persisted reports in the DB - $dto->timeEntryType = isset($data->timeEntryType) ? TimeEntryType::from($data->timeEntryType) : null; + // Note: timeEntryType was added later, reports persisted before that are missing the value and default to "work" + if (property_exists($data, 'timeEntryType')) { + $dto->timeEntryType = $data->timeEntryType !== null ? TimeEntryType::from($data->timeEntryType) : null; + } else { + $dto->timeEntryType = TimeEntryType::Work; + } return $dto; } diff --git a/tests/Unit/Service/Dto/ReportPropertiesDtoTest.php b/tests/Unit/Service/Dto/ReportPropertiesDtoTest.php new file mode 100644 index 00000000..7169c6de --- /dev/null +++ b/tests/Unit/Service/Dto/ReportPropertiesDtoTest.php @@ -0,0 +1,91 @@ + + */ + private function getBaseProperties(): array + { + return [ + 'group' => 'project', + 'subGroup' => 'task', + 'historyGroup' => 'day', + 'weekStart' => 'monday', + 'timezone' => 'Europe/Vienna', + 'start' => '2024-01-01T00:00:00Z', + 'end' => '2024-01-31T00:00:00Z', + 'active' => null, + 'memberIds' => null, + 'billable' => null, + 'clientIds' => null, + 'projectIds' => null, + 'tagIds' => null, + 'taskIds' => null, + ]; + } + + /** + * @param array $properties + */ + private function castFromJson(array $properties): ReportPropertiesDto + { + $json = json_encode($properties); + $this->assertIsString($json); + + return ReportPropertiesDto::castUsing([])->get(new Report, 'properties', $json, []); + } + + public function test_time_entry_type_defaults_to_work_if_the_value_is_missing_in_the_persisted_report(): void + { + // Arrange + $properties = $this->getBaseProperties(); + + // Act + $dto = $this->castFromJson($properties); + + // Assert + $this->assertSame(TimeEntryType::Work, $dto->timeEntryType); + } + + public function test_time_entry_type_is_null_if_the_persisted_report_has_it_set_to_null(): void + { + // Arrange + $properties = $this->getBaseProperties(); + $properties['timeEntryType'] = null; + + // Act + $dto = $this->castFromJson($properties); + + // Assert + $this->assertNull($dto->timeEntryType); + } + + public function test_time_entry_type_is_casted_to_the_enum_if_the_persisted_report_has_a_value(): void + { + // Arrange + $propertiesWork = $this->getBaseProperties(); + $propertiesWork['timeEntryType'] = 'work'; + $propertiesBreak = $this->getBaseProperties(); + $propertiesBreak['timeEntryType'] = 'break'; + + // Act + $dtoWork = $this->castFromJson($propertiesWork); + $dtoBreak = $this->castFromJson($propertiesBreak); + + // Assert + $this->assertSame(TimeEntryType::Work, $dtoWork->timeEntryType); + $this->assertSame(TimeEntryType::Break, $dtoBreak->timeEntryType); + } +}