create(); /** @var Route $route */ $route = Route::factory()->active()->create(['feed_id' => $feed->id]); $article = Article::factory()->create(['feed_id' => $feed->id, 'title' => 'A Headline']); /** @var RouteArticle $routeArticle */ $routeArticle = RouteArticle::factory()->forRoute($route)->create([ 'article_id' => $article->id, 'approval_status' => ApprovalStatusEnum::PENDING, 'validated_at' => now(), ]); return $routeArticle; } public function test_approving_records_activity(): void { Event::fake([RouteArticleApproved::class]); $this->pendingRouteArticle()->approve(); $log = ActivityLog::ofType(ActivityTypeEnum::APPROVE)->first(); $this->assertNotNull($log); $this->assertStringContainsString('A Headline', $log->message); $this->assertSame(Article::class, $log->subject_type); } public function test_rejecting_records_activity(): void { $this->pendingRouteArticle()->reject(); $log = ActivityLog::ofType(ActivityTypeEnum::REJECT)->first(); $this->assertNotNull($log); $this->assertStringContainsString('A Headline', $log->message); } public function test_approving_an_already_approved_article_records_nothing(): void { Event::fake([RouteArticleApproved::class]); $routeArticle = $this->pendingRouteArticle(); $routeArticle->approve(); $routeArticle->approve(); $this->assertSame(1, ActivityLog::ofType(ActivityTypeEnum::APPROVE)->count()); } public function test_rejecting_an_already_rejected_article_records_nothing(): void { $routeArticle = $this->pendingRouteArticle(); $routeArticle->reject(); $routeArticle->reject(); $this->assertSame(1, ActivityLog::ofType(ActivityTypeEnum::REJECT)->count()); } public function test_clearing_pending_articles_records_one_summary_entry(): void { $routeArticle = $this->pendingRouteArticle(); $this->pendingRouteArticle(); Livewire::test(Articles::class)->call('clear'); $entries = ActivityLog::ofType(ActivityTypeEnum::REJECT)->get(); $this->assertCount(1, $entries); $this->assertStringContainsString('2 pending articles', $entries->first()->message); $this->assertSame(ApprovalStatusEnum::REJECTED, $routeArticle->fresh()->approval_status); } public function test_clearing_nothing_records_no_entry(): void { Livewire::test(Articles::class)->call('clear'); $this->assertSame(0, ActivityLog::count()); } public function test_one_event_records_exactly_one_entry(): void { ActivityLogged::dispatch(ActivityTypeEnum::FETCH, 'Single entry'); $this->assertSame(1, ActivityLog::where('message', 'Single entry')->count()); } public function test_a_long_message_is_truncated_to_fit_the_column(): void { ActivityLogged::dispatch(ActivityTypeEnum::PUBLISH, str_repeat('a', 400)); $this->assertSame(255, strlen(ActivityLog::first()->message)); } public function test_an_empty_context_is_stored_as_null(): void { ActivityLogged::dispatch(ActivityTypeEnum::FETCH, 'No context'); $this->assertNull(ActivityLog::first()->context); } }