From b0cdeb3e33cd667e3243837df80605194c343fe0 Mon Sep 17 00:00:00 2001 From: Constantin Graf Date: Wed, 5 Jun 2024 23:13:04 +0200 Subject: [PATCH] Fixed test case and travelTo function in test cases --- app/Service/Import/ImportService.php | 2 +- database/seeders/DatabaseSeeder.php | 8 ++++-- tests/TestCase.php | 15 +++++++++++ .../Endpoint/Api/V1/TimeEntryEndpointTest.php | 26 ++++++++++++------- tests/Unit/Service/DashboardServiceTest.php | 5 ++-- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/app/Service/Import/ImportService.php b/app/Service/Import/ImportService.php index 4cdd4274..c8acf866 100644 --- a/app/Service/Import/ImportService.php +++ b/app/Service/Import/ImportService.php @@ -9,7 +9,7 @@ use App\Service\Import\Importers\ImporterContract; use App\Service\Import\Importers\ImporterProvider; use App\Service\Import\Importers\ImportException; use App\Service\Import\Importers\ReportDto; -use Carbon\Carbon; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 1da89ff6..79308e7b 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -39,7 +39,7 @@ class DatabaseSeeder extends Seeder 'personal_team' => false, 'currency' => 'EUR', ]); - $userRivalManager = User::factory()->withPersonalOrganization()->create([ + $userAcmeManager = User::factory()->withPersonalOrganization()->create([ 'name' => 'Acme Manager', 'email' => 'test@example.com', ]); @@ -57,7 +57,7 @@ class DatabaseSeeder extends Seeder 'password' => null, ]); $userAcmeOwnerMember = Member::factory()->forUser($userAcmeOwner)->forOrganization($organizationAcme)->role(Role::Owner)->create(); - $userAcmeManagerMember = Member::factory()->forUser($userRivalManager)->forOrganization($organizationAcme)->role(Role::Manager)->create(); + $userAcmeManagerMember = Member::factory()->forUser($userAcmeManager)->forOrganization($organizationAcme)->role(Role::Manager)->create(); $userAcmeAdminMember = Member::factory()->forUser($userAcmeAdmin)->forOrganization($organizationAcme)->role(Role::Admin)->create(); $userAcmeEmployeeMember = Member::factory()->forUser($userAcmeEmployee)->forOrganization($organizationAcme)->role(Role::Employee)->create(); $userAcmePlaceholderMember = Member::factory()->forUser($userAcmePlaceholder)->forOrganization($organizationAcme)->role(Role::Placeholder)->create(); @@ -67,6 +67,10 @@ class DatabaseSeeder extends Seeder ->count(10) ->forMember($userAcmeAdminMember) ->create(); + TimeEntry::factory() + ->count(10) + ->forMember($userAcmeManagerMember) + ->create(); TimeEntry::factory() ->count(10) ->forMember($userAcmePlaceholderMember) diff --git a/tests/TestCase.php b/tests/TestCase.php index e946ab2b..42bee124 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,8 +5,10 @@ declare(strict_types=1); namespace Tests; use App\Service\PermissionStore; +use Carbon\CarbonImmutable; use Illuminate\Database\Eloquent\Collection; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Mail; use TiMacDonald\Log\LogFake; @@ -32,4 +34,17 @@ abstract class TestCase extends BaseTestCase { $this->assertEqualsCanonicalizing($ids, $models->pluck('id')->toArray()); } + + /** + * Set the current time to the given time. + * This method fixes a bug, that setting the test now with Carbon::setTestNow() with a Carbon instance that has a timezone set, will not work as expected. + * IT will also set the timezone for model casts with type "datetime" to the timezone and not use the timezone configured in the configuration "app.timezone". + * + * @param Carbon|CarbonImmutable $date + * @param callable|null $callback + */ + public function travelTo($date, $callback = null): void + { + parent::travelTo($date->utc()); + } } diff --git a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php index b9b44c49..4b5059e8 100644 --- a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php +++ b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php @@ -240,39 +240,36 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract public function test_index_endpoint_filter_only_full_dates_returns_time_entries_for_the_whole_day_case_more_time_entries_than_limit_with_a_timezone_edge_case(): void { // Arrange + $now = Carbon::create(2024, 1, 1, 12, 0, 0, 'Europe/Vienna'); + $this->freezeTime($now); $data = $this->createUserWithPermission([ 'time-entries:view:own', ]); $data->user->timezone = 'America/New_York'; $data->user->save(); /** - * We create in the eyes of the users timezone 2 time entries yesterday, 5 time entries two days ago, and 3 time entries three days ago + * We create in the eyes of the users timezone 2 time entries yesterday, 2 time entries two days ago, and 3 time entries three days ago * The time entries are created in a way that they jump to the next day if the endpoint ignores the users timezone and just uses UTC */ // Note: This entry is yesterday in user timezone and yesterday in UTC $timeEntriesDay1InUserTimeZone = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member) ->state([ - 'start' => Carbon::now($data->user->timezone)->subDay()->startOfDay()->utc(), + 'start' => Carbon::now()->timezone($data->user->timezone)->subDay()->startOfDay()->utc(), ]) ->createMany(2); - //dump($timeEntriesDay1InUserTimeZone->first()->refresh()->start->toImmutable()->timezone('UTC')->toDateString()); - //dump($timeEntriesDay1InUserTimeZone->first()->refresh()->start->toImmutable()->timezone($data->user->timezone)->toDateString()); // Note: This entry is yesterday in UTC timezone, but two days ago in user timezone $timeEntriesDay1InUTC = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member) ->state([ - 'start' => Carbon::now('UTC')->subDay()->startOfDay()->utc(), + 'start' => Carbon::now()->utc()->subDay()->startOfDay()->utc(), ]) ->createMany(2); - //dump($timeEntriesDay1InUTC->first()->refresh()->start->toImmutable()->timezone('UTC')->toDateString()); - //dump($timeEntriesDay1InUTC->first()->refresh()->start->toImmutable()->timezone($data->user->timezone)->toDateString()); // Note: This entry is two days ago in user timezone $timeEntriesDay2InUserTimeZone = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member) ->state([ - 'start' => Carbon::now($data->user->timezone)->subDays(2)->startOfDay()->utc(), + 'start' => Carbon::now()->timezone($data->user->timezone)->subDays(2)->startOfDay()->utc(), ]) ->createMany(3); - Passport::actingAs($data->user); // Act @@ -291,12 +288,21 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract public function test_index_endpoint_filter_only_full_dates_returns_time_entries_for_the_whole_day_case_more_time_entries_in_latest_day_than_limit(): void { // Arrange + $now = Carbon::create(2024, 1, 1, 12, 0, 0, 'Europe/Vienna'); + $this->freezeTime($now); $data = $this->createUserWithPermission([ 'time-entries:view:own', ]); $timeEntriesDay1 = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member) - ->startBetween(Carbon::now()->subDay()->startOfDay(), Carbon::now()->subDay()->endOfDay(), true) + ->state([ + 'start' => Carbon::now()->timezone($data->user->timezone)->subDay()->startOfDay()->utc(), + ]) ->createMany(7); + $timeEntriesDay2 = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member) + ->state([ + 'start' => Carbon::now()->timezone($data->user->timezone)->subDays(2)->endOfDay()->utc(), + ]) + ->createMany(3); Passport::actingAs($data->user); // Act diff --git a/tests/Unit/Service/DashboardServiceTest.php b/tests/Unit/Service/DashboardServiceTest.php index 490a390f..0ec42db8 100644 --- a/tests/Unit/Service/DashboardServiceTest.php +++ b/tests/Unit/Service/DashboardServiceTest.php @@ -13,7 +13,6 @@ use App\Models\Task; use App\Models\TimeEntry; use App\Models\User; use App\Service\DashboardService; -use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Carbon; use Tests\TestCase; @@ -261,7 +260,7 @@ class DashboardServiceTest extends TestCase { // Arrange // Note: Is a Monday - $now = CarbonImmutable::create(2024, 1, 1, 12, 0, 0, 'Europe/Vienna'); + $now = Carbon::create(2024, 1, 1, 12, 0, 0, 'Europe/Vienna')->toImmutable(); $this->travelTo($now); $user = User::factory()->create([ 'timezone' => 'Europe/Vienna', @@ -337,7 +336,7 @@ class DashboardServiceTest extends TestCase { // Arrange // Note: Is a Monday - $now = CarbonImmutable::create(2024, 1, 1, 12, 0, 0, 'Europe/Vienna'); + $now = Carbon::create(2024, 1, 1, 12, 0, 0, 'Europe/Vienna')->toImmutable(); $this->travelTo($now); $organization = Organization::factory()->create(); $user = User::factory()->create([