Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
117 lines
3.7 KiB
PHP
117 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Panel;
|
|
|
|
use App\Filament\Resources\SettingsResource;
|
|
use App\Filament\Resources\SettingsResource\Pages\EditSettings;
|
|
use App\Models\Setting;
|
|
use Database\Seeders\RolePermissionSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Livewire\Livewire;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use Tests\FakesPireon;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* The generic settings editor.
|
|
*
|
|
* A setting holds arbitrary JSON — `site.maintenance` is a map containing a
|
|
* map of translations — so the thing this screen must never do is flatten it.
|
|
*/
|
|
class SettingsResourceTest extends TestCase
|
|
{
|
|
use FakesPireon, RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->seed(RolePermissionSeeder::class);
|
|
}
|
|
|
|
#[Test]
|
|
public function the_list_renders_whatever_shape_a_setting_has(): void
|
|
{
|
|
Setting::set('site.maintenance', ['enabled' => false, 'message' => ['es' => 'Hola']]);
|
|
Setting::set('un.escalar', 'texto');
|
|
Setting::set('una.lista', [1, 2, 3]);
|
|
|
|
$this->actingAs($this->userWithRoles('super_admin'));
|
|
|
|
$this->get(SettingsResource::getUrl('index'))->assertSuccessful();
|
|
}
|
|
|
|
#[Test]
|
|
public function a_nested_setting_survives_a_round_trip(): void
|
|
{
|
|
$value = [
|
|
'enabled' => true,
|
|
'message' => ['es' => 'Volvemos en un rato', 'ca' => 'Tornem de seguida'],
|
|
'until' => null,
|
|
];
|
|
|
|
Setting::set('site.maintenance', $value);
|
|
|
|
$this->actingAs($this->userWithRoles('super_admin'));
|
|
|
|
Livewire::test(EditSettings::class, ['record' => 'site.maintenance'])
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
|
|
// Opening and saving without touching anything must leave every
|
|
// translation exactly as it was. A key/value grid would have written
|
|
// back the word "Array" here.
|
|
// assertEquals, not assertSame: Postgres stores these as jsonb,
|
|
// which does not preserve object key order. Every value here is a map
|
|
// whose order carries no meaning.
|
|
$this->assertEquals($value, Setting::get('site.maintenance'));
|
|
}
|
|
|
|
#[Test]
|
|
public function a_nested_value_can_be_edited(): void
|
|
{
|
|
Setting::set('site.maintenance', ['enabled' => false, 'message' => ['es' => 'Antiguo']]);
|
|
|
|
$this->actingAs($this->userWithRoles('super_admin'));
|
|
|
|
Livewire::test(EditSettings::class, ['record' => 'site.maintenance'])
|
|
->fillForm(['value' => json_encode(['enabled' => true, 'message' => ['es' => 'Nuevo', 'ca' => 'Nou']])])
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
|
|
$this->assertEquals(
|
|
['enabled' => true, 'message' => ['es' => 'Nuevo', 'ca' => 'Nou']],
|
|
Setting::get('site.maintenance'),
|
|
);
|
|
}
|
|
|
|
#[Test]
|
|
public function a_typo_is_refused_rather_than_stored(): void
|
|
{
|
|
Setting::set('site.maintenance', ['enabled' => false]);
|
|
|
|
$this->actingAs($this->userWithRoles('super_admin'));
|
|
|
|
Livewire::test(EditSettings::class, ['record' => 'site.maintenance'])
|
|
->fillForm(['value' => '{"enabled": tru}'])
|
|
->call('save')
|
|
->assertHasFormErrors(['value']);
|
|
|
|
// Invalid JSON must not reach a column the whole application reads.
|
|
$this->assertSame(['enabled' => false], Setting::get('site.maintenance'));
|
|
}
|
|
|
|
#[Test]
|
|
public function an_editor_may_look_but_not_touch(): void
|
|
{
|
|
Setting::set('site.maintenance', ['enabled' => false]);
|
|
|
|
$editor = $this->userWithRoles('editor');
|
|
|
|
$this->assertTrue($editor->can('settings.view'));
|
|
$this->assertFalse($editor->can('settings.update'));
|
|
}
|
|
}
|