Certified/tests/Feature/Certificates/CertificateIndexTest.php
2026-08-09 16:33:53 +02:00

140 lines
4.9 KiB
PHP

<?php
use App\Models\Category;
use App\Models\Certificate;
use App\Models\User;
use Livewire\Livewire;
test('guests are redirected to the login page', function () {
$this->get(route('certificates.index'))->assertRedirect(route('login'));
});
test('authenticated users can view the certificates page', function () {
$this->actingAs(User::factory()->create());
$this->get(route('certificates.index'))->assertOk();
});
test('users only see their own certificates', function () {
$user = User::factory()->create();
$other = User::factory()->create();
Certificate::factory()->for($user)->create(['title' => 'My Own Diploma']);
Certificate::factory()->for($other)->create(['title' => 'Foreign Diploma']);
$this->actingAs($user);
$this->get(route('certificates.index'))
->assertSee('My Own Diploma')
->assertDontSee('Foreign Diploma');
});
test('certificates can be filtered by category', function () {
$this->actingAs($user = User::factory()->create());
$category = Category::factory()->for($user)->create();
Certificate::factory()->for($user)->create(['title' => 'Categorized One', 'category_id' => $category->id]);
Certificate::factory()->for($user)->create(['title' => 'Uncategorized One']);
Livewire::test('pages::certificates.index')
->set('categoryFilter', (string) $category->id)
->assertSee('Categorized One')
->assertDontSee('Uncategorized One');
});
test('certificates can be sorted by title in both directions', function () {
$this->actingAs($user = User::factory()->create());
Certificate::factory()->for($user)->create(['title' => 'Alpha Certificate']);
Certificate::factory()->for($user)->create(['title' => 'Zulu Certificate']);
Livewire::test('pages::certificates.index')
->call('sort', 'title')
->assertSet('sortBy', 'title')
->assertSet('sortDirection', 'asc')
->assertSeeInOrder(['Alpha Certificate', 'Zulu Certificate'])
->call('sort', 'title')
->assertSet('sortDirection', 'desc')
->assertSeeInOrder(['Zulu Certificate', 'Alpha Certificate']);
});
test('certificates are sorted by expiry date by default', function () {
$this->actingAs($user = User::factory()->create());
Certificate::factory()->for($user)->create(['title' => 'Later Cert', 'expires_at' => now()->addYears(2)]);
Certificate::factory()->for($user)->create(['title' => 'Sooner Cert', 'expires_at' => now()->addMonths(3)]);
Livewire::test('pages::certificates.index')
->assertSet('sortBy', 'expires_at')
->assertSeeInOrder(['Sooner Cert', 'Later Cert']);
});
test('invalid sort columns are ignored', function () {
$this->actingAs(User::factory()->create());
Livewire::test('pages::certificates.index')
->call('sort', 'user_id')
->assertSet('sortBy', 'expires_at');
});
test('sorting and filtering are initialized from the query string', function () {
$this->actingAs(User::factory()->create());
Livewire::withQueryParams(['sort' => 'title', 'direction' => 'desc'])
->test('pages::certificates.index')
->assertSet('sortBy', 'title')
->assertSet('sortDirection', 'desc');
});
test('the certificate list is paginated', function () {
$this->actingAs($user = User::factory()->create());
Certificate::factory()->for($user)->count(15)->create();
$certificates = Livewire::test('pages::certificates.index')->instance()->certificates;
expect($certificates->count())->toBe(10)
->and($certificates->total())->toBe(15);
});
test('changing the category filter resets pagination', function () {
$this->actingAs($user = User::factory()->create());
Certificate::factory()->for($user)->count(15)->create();
Livewire::test('pages::certificates.index')
->call('nextPage')
->set('categoryFilter', '')
->assertSet('paginators.page', 1);
});
test('expired certificates show an expired badge', function () {
$this->actingAs($user = User::factory()->create());
Certificate::factory()->for($user)->expired()->create();
$this->get(route('certificates.index'))->assertSee('Expired');
});
test('the free plan usage is shown and the add button is enabled below the limit', function () {
$this->actingAs($user = User::factory()->create());
Certificate::factory()->for($user)->count(3)->create();
$this->get(route('certificates.index'))
->assertOk()
->assertSee('3')
->assertSee('5')
->assertSee(route('certificates.create'), false);
});
test('the add button links to pricing once the free plan limit is reached', function () {
$this->actingAs($user = User::factory()->create());
Certificate::factory()->for($user)->count(5)->create();
$this->get(route('certificates.index'))
->assertOk()
->assertSee(route('marketing.pricing'), false)
->assertDontSee(route('certificates.create'), false);
});