Initial commit: Pireon Admin — headless admin panel and public API

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>
This commit is contained in:
2026-08-19 17:55:27 +02:00
commit 3897113313
534 changed files with 64050 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
<?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'));
}
}