Add a statistics page to the panel
The most read, reads per language with a daily chart, and published content nobody opened, each compared with the period before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
83
tests/Feature/Panel/StatisticsTest.php
Normal file
83
tests/Feature/Panel/StatisticsTest.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature\Panel;
|
||||
|
||||
use App\Filament\Pages\Statistics;
|
||||
use App\Models\ContentView;
|
||||
use App\Models\Page;
|
||||
use App\Models\Project;
|
||||
use App\Support\ViewStats;
|
||||
use Database\Seeders\RolePermissionSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Livewire\Livewire;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Tests\FakesPireon;
|
||||
use Tests\TestCase;
|
||||
|
||||
class StatisticsTest extends TestCase
|
||||
{
|
||||
use FakesPireon, RefreshDatabase;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->seed(RolePermissionSeeder::class);
|
||||
$this->travelTo('2026-10-15 12:00:00');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function the_most_read_compare_with_the_period_before(): void
|
||||
{
|
||||
$page = Page::factory()->published()->create(['title' => ['es' => 'Leída']]);
|
||||
|
||||
$this->travelTo('2026-09-10 12:00:00');
|
||||
ContentView::record($page, 'es', 10);
|
||||
$this->travelTo('2026-10-14 12:00:00');
|
||||
ContentView::record($page, 'es', 15);
|
||||
ContentView::record($page, 'en', 5);
|
||||
$this->travelTo('2026-10-15 12:00:00');
|
||||
|
||||
$stats = new ViewStats(30);
|
||||
$top = $stats->top()->first();
|
||||
|
||||
$this->assertSame('Leída', $top['title']);
|
||||
$this->assertSame(20, $top['views']);
|
||||
$this->assertSame(10, $top['previous']);
|
||||
$this->assertSame(['views' => 15, 'previous' => 10, 'share' => 75.0], $stats->byLocale()['es']);
|
||||
$this->assertSame(30, count($stats->daily()['labels']));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function published_content_nobody_read_is_listed(): void
|
||||
{
|
||||
$read = Page::factory()->published()->create();
|
||||
Page::factory()->published()->create(['title' => ['es' => 'Olvidada']]);
|
||||
Page::factory()->draft()->create(['title' => ['es' => 'Borrador']]);
|
||||
ContentView::record($read, 'es');
|
||||
|
||||
$titles = (new ViewStats(30))->unread()->pluck('title');
|
||||
|
||||
$this->assertContains('Olvidada', $titles);
|
||||
$this->assertNotContains('Borrador', $titles);
|
||||
$this->assertNotContains($read->getTranslation('title', 'es'), $titles);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function the_page_opens_and_switches_period(): void
|
||||
{
|
||||
$this->actingAs($this->userWithRoles('writer'));
|
||||
|
||||
Project::factory()->published()->create();
|
||||
|
||||
$this->get(Statistics::getUrl())->assertOk();
|
||||
|
||||
Livewire::test(Statistics::class)
|
||||
->set('days', 7)
|
||||
->assertSet('days', 7)
|
||||
->set('days', 12)
|
||||
->assertSet('days', 30);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user