create(); $role = Role::firstOrCreate(['name' => 'ROLE_ADMIN'], ['color' => '#111111']); $admin->roles()->attach($role); return $admin; } it('lists settings and supports key filtering', function (): void { Setting::create(['key' => 'site.name', 'value' => 'SpeedBB']); Setting::create(['key' => 'site.tagline', 'value' => 'Fast']); $response = $this->getJson('/api/settings'); $response->assertOk(); $payload = $response->json(); expect($payload)->toBeArray(); expect(count($payload))->toBeGreaterThanOrEqual(2); $response->assertJsonFragment(['key' => 'site.name', 'value' => 'SpeedBB']); $response->assertJsonFragment(['key' => 'site.tagline', 'value' => 'Fast']); $response = $this->getJson('/api/settings?key=site.name'); $response->assertOk(); $response->assertJsonCount(1); $response->assertJsonFragment(['key' => 'site.name', 'value' => 'SpeedBB']); }); it('forbids non-admin setting creation', function (): void { $user = User::factory()->create(); Sanctum::actingAs($user); $response = $this->postJson('/api/settings', [ 'key' => 'site.name', 'value' => 'SpeedBB', ]); $response->assertStatus(403); }); it('creates or updates settings as admin', function (): void { $admin = makeAdminUser(); Sanctum::actingAs($admin); $response = $this->postJson('/api/settings', [ 'key' => 'site.name', 'value' => 'SpeedBB', ]); $response->assertOk(); $response->assertJsonFragment(['key' => 'site.name', 'value' => 'SpeedBB']); $response = $this->postJson('/api/settings', [ 'key' => 'site.name', 'value' => 'SpeedBB 2', ]); $response->assertOk(); $this->assertDatabaseHas('settings', [ 'key' => 'site.name', 'value' => 'SpeedBB 2', ]); }); it('bulk stores settings as admin', function (): void { $admin = makeAdminUser(); Sanctum::actingAs($admin); $response = $this->postJson('/api/settings/bulk', [ 'settings' => [ ['key' => 'site.name', 'value' => 'SpeedBB'], ['key' => 'site.tagline', 'value' => 'Fast'], ], ]); $response->assertOk(); $response->assertJsonCount(2); $this->assertDatabaseHas('settings', [ 'key' => 'site.tagline', 'value' => 'Fast', ]); });