126 lines
3.9 KiB
PHP
126 lines
3.9 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Feature;
|
||
|
|
|
||
|
|
use App\Enums\ActivityTypeEnum;
|
||
|
|
use App\Enums\ApprovalStatusEnum;
|
||
|
|
use App\Events\ActivityLogged;
|
||
|
|
use App\Events\RouteArticleApproved;
|
||
|
|
use App\Livewire\Articles;
|
||
|
|
use App\Models\ActivityLog;
|
||
|
|
use App\Models\Article;
|
||
|
|
use App\Models\Feed;
|
||
|
|
use App\Models\Route;
|
||
|
|
use App\Models\RouteArticle;
|
||
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
|
|
use Illuminate\Support\Facades\Event;
|
||
|
|
use Livewire\Livewire;
|
||
|
|
use Tests\TestCase;
|
||
|
|
|
||
|
|
class ActivityRecordingTest extends TestCase
|
||
|
|
{
|
||
|
|
use RefreshDatabase;
|
||
|
|
|
||
|
|
private function pendingRouteArticle(): RouteArticle
|
||
|
|
{
|
||
|
|
$feed = Feed::factory()->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);
|
||
|
|
}
|
||
|
|
}
|