create(); $category = NewsCategory::query()->create([ 'name' => 'Announcements', 'slug' => 'announcements', 'description' => 'Announcement category', 'position' => 0, 'is_active' => true, ]); $dueArticle = NewsArticle::query()->create([ 'title' => 'Due scheduled article', 'slug' => 'due-scheduled-article', 'excerpt' => 'Due now.', 'content' => 'Body', 'author_id' => $author->id, 'category_id' => $category->id, 'type' => NewsArticle::TYPE_ANNOUNCEMENT, 'status' => 'scheduled', 'editorial_status' => NewsArticle::EDITORIAL_STATUS_SCHEDULED, 'published_at' => now()->subMinute(), ]); $futureArticle = NewsArticle::query()->create([ 'title' => 'Future scheduled article', 'slug' => 'future-scheduled-article', 'excerpt' => 'Not due yet.', 'content' => 'Body', 'author_id' => $author->id, 'category_id' => $category->id, 'type' => NewsArticle::TYPE_ANNOUNCEMENT, 'status' => 'scheduled', 'editorial_status' => NewsArticle::EDITORIAL_STATUS_SCHEDULED, 'published_at' => now()->addHour(), ]); $this->artisan('news:publish-scheduled') ->expectsOutput(sprintf('Published News article #%d: "%s"', $dueArticle->id, $dueArticle->title)) ->expectsOutput('Done. Published: 1, Errors: 0.') ->assertSuccessful(); expect($dueArticle->fresh()) ->editorial_status->toBe(NewsArticle::EDITORIAL_STATUS_PUBLISHED) ->status->toBe('published') ->and($futureArticle->fresh()) ->editorial_status->toBe(NewsArticle::EDITORIAL_STATUS_SCHEDULED) ->status->toBe('scheduled'); }); it('supports dry run for scheduled news publishing', function (): void { $author = User::factory()->create(); $category = NewsCategory::query()->create([ 'name' => 'Platform', 'slug' => 'platform', 'description' => 'Platform category', 'position' => 0, 'is_active' => true, ]); $article = NewsArticle::query()->create([ 'title' => 'Dry run article', 'slug' => 'dry-run-article', 'excerpt' => 'Due but not published in dry run.', 'content' => 'Body', 'author_id' => $author->id, 'category_id' => $category->id, 'type' => NewsArticle::TYPE_PLATFORM_UPDATE, 'status' => 'scheduled', 'editorial_status' => NewsArticle::EDITORIAL_STATUS_SCHEDULED, 'published_at' => now()->subMinute(), ]); $this->artisan('news:publish-scheduled', ['--dry-run' => true]) ->expectsOutput(sprintf('[dry-run] Would publish News article #%d: "%s"', $article->id, $article->title)) ->assertSuccessful(); expect($article->fresh()) ->editorial_status->toBe(NewsArticle::EDITORIAL_STATUS_SCHEDULED) ->status->toBe('scheduled'); });