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:
2026-10-01 10:19:19 +02:00
parent 8d0f81f9c5
commit 697d333ad4
9 changed files with 605 additions and 0 deletions

View 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);
}
}