From d17d98a5ecd45a0ee43000970c73844ec9f2f10c Mon Sep 17 00:00:00 2001 From: myrmidex Date: Sat, 15 Aug 2026 10:12:41 +0200 Subject: [PATCH] 152 - Freeze time in the publish job tests and cover the midnight boundary --- tests/Unit/Jobs/PublishNextArticleJobTest.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/Unit/Jobs/PublishNextArticleJobTest.php b/tests/Unit/Jobs/PublishNextArticleJobTest.php index c813d9d6..75d350b9 100644 --- a/tests/Unit/Jobs/PublishNextArticleJobTest.php +++ b/tests/Unit/Jobs/PublishNextArticleJobTest.php @@ -23,6 +23,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Carbon; use Mockery; use Tests\TestCase; @@ -35,6 +36,11 @@ class PublishNextArticleJobTest extends TestCase protected function setUp(): void { parent::setUp(); + + // The daily cap counts from startOfDay, so tests placing publications a + // couple of hours back land on the previous day when run after midnight. + Carbon::setTestNow('2026-07-15 12:00:00'); + $this->notificationService = new NotificationService; } @@ -319,6 +325,54 @@ public function test_daily_cap_counts_each_channel_publication_separately(): voi $this->assertTrue(true); } + public function test_daily_cap_counts_from_midnight_not_a_rolling_window(): void + { + Carbon::setTestNow('2026-07-15 01:00:00'); + + $this->createApprovedRouteArticle(); + + ArticlePublication::factory()->count(3)->create(['published_at' => Carbon::parse('2026-07-14 23:00:00')]); + Setting::setArticlePublishingInterval(0); + Setting::setDailyPublishCap(3); + + $articleFetcherMock = Mockery::mock(FetchArticleDataAction::class); + $articleFetcherMock->shouldReceive('execute') + ->once() + ->andReturn(['title' => 'Test Article', 'description' => 'Test description']); + + $publishingServiceMock = Mockery::mock(ArticlePublishingService::class); + $publishingServiceMock->shouldReceive('publishRouteArticle') + ->once() + ->andReturn(PublishOutcome::published($this->makePublication())); + + $job = new PublishNextArticleJob; + $job->handle(new PublishRouteArticleAction($articleFetcherMock, $publishingServiceMock, $this->notificationService)); + + $this->assertTrue(true); + } + + public function test_daily_cap_counts_a_publication_just_after_midnight(): void + { + Carbon::setTestNow('2026-07-15 01:00:00'); + + $this->createApprovedRouteArticle(); + + ArticlePublication::factory()->count(3)->create(['published_at' => Carbon::parse('2026-07-15 00:30:00')]); + Setting::setArticlePublishingInterval(0); + Setting::setDailyPublishCap(3); + + $articleFetcherMock = Mockery::mock(FetchArticleDataAction::class); + $publishingServiceMock = Mockery::mock(ArticlePublishingService::class); + + $articleFetcherMock->shouldNotReceive('execute'); + $publishingServiceMock->shouldNotReceive('publishRouteArticle'); + + $job = new PublishNextArticleJob; + $job->handle(new PublishRouteArticleAction($articleFetcherMock, $publishingServiceMock, $this->notificationService)); + + $this->assertTrue(true); + } + public function test_handle_ignores_publications_from_previous_days(): void { $this->createApprovedRouteArticle(); @@ -572,6 +626,7 @@ public function test_job_can_be_serialized(): void protected function tearDown(): void { + Carbon::setTestNow(); Mockery::close(); parent::tearDown(); }