cms/tests/Feature/RolePermissionTest.php

263 lines
9.8 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Tests\Feature;
use App\Models\Permission;
use App\Models\Role;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class RolePermissionTest extends TestCase
{
use RefreshDatabase;
public function test_custom_role_with_theme_permissions_can_access_admin_dashboard(): void
{
// 1. Seed permissions
$this->seed(\Database\Seeders\PermissionSeeder::class);
// 2. Create the 'Theme Manager' role
$role = Role::create([
'name' => 'Theme Manager',
'slug' => 'theme-manager',
'description' => 'Can manage themes',
]);
// 3. Assign theme related permissions
$themePermissions = Permission::whereIn('slug', [
'view-themes',
'activate-themes',
'upload-themes',
'edit-themes'
])->pluck('id');
$role->permissions()->sync($themePermissions);
// 4. Create user and assign the role
$user = User::factory()->create([
'email' => 'themes@siteweaver.test'
]);
$user->roles()->attach($role);
// 5. Try to access the admin dashboard
$adminPath = env('ADMIN_PATH', 'loom');
$response = $this->actingAs($user)->get('/' . $adminPath);
$response->assertStatus(200);
// 6. Try to access the themes index
$response = $this->actingAs($user)->get('/' . $adminPath . '/themes');
$response->assertStatus(200);
// 7. Try to access the theme editor
$response = $this->actingAs($user)->get('/' . $adminPath . '/themes/editor');
$response->assertStatus(200);
// 8. Try to access pages (should fail as they don't have view-pages)
$response = $this->actingAs($user)->get('/' . $adminPath . '/pages');
$response->assertStatus(403);
}
public function test_editor_can_access_dashboard_and_pages(): void
{
$this->seed(\Database\Seeders\PermissionSeeder::class);
$this->seed(\Database\Seeders\RoleSeeder::class);
$user = User::factory()->create();
$user->roles()->attach(Role::where('slug', 'editor')->first());
$adminPath = env('ADMIN_PATH', 'loom');
$response = $this->actingAs($user)->get('/' . $adminPath);
$response->assertStatus(200);
$response = $this->actingAs($user)->get('/' . $adminPath . '/pages');
$response->assertStatus(200);
// Editor cannot view users
$response = $this->actingAs($user)->get('/' . $adminPath . '/users');
$response->assertStatus(403);
}
public function test_admin_has_global_access_via_middleware_bypass(): void
{
$this->seed(\Database\Seeders\PermissionSeeder::class);
$this->seed(\Database\Seeders\RoleSeeder::class);
// Create an admin user - note that in the seeder, 'admin' role might have permissions,
// but we want to test the bypass specifically.
$user = User::factory()->create();
$user->roles()->attach(Role::where('slug', 'admin')->first());
$adminPath = env('ADMIN_PATH', 'loom');
// Admin can access everything
$this->actingAs($user)->get('/' . $adminPath)->assertStatus(200);
$this->actingAs($user)->get('/' . $adminPath . '/pages')->assertStatus(200);
$this->actingAs($user)->get('/' . $adminPath . '/users')->assertStatus(200);
$this->actingAs($user)->get('/' . $adminPath . '/roles')->assertStatus(200);
$this->actingAs($user)->get('/' . $adminPath . '/analytics')->assertStatus(200);
}
public function test_editor_loses_access_when_permission_is_removed(): void
{
$this->seed(\Database\Seeders\PermissionSeeder::class);
$this->seed(\Database\Seeders\RoleSeeder::class);
$user = User::factory()->create();
$role = Role::where('slug', 'editor')->first();
$user->roles()->attach($role);
$adminPath = env('ADMIN_PATH', 'loom');
// Initially has access
$this->actingAs($user)->get('/' . $adminPath . '/pages')->assertStatus(200);
// Remove the permission from the role
$permission = Permission::where('slug', 'view-pages')->first();
$role->permissions()->detach($permission->id);
// Now should be forbidden (403)
$this->actingAs($user)->get('/' . $adminPath . '/pages')->assertStatus(403);
}
public function test_navigation_and_dashboard_items_hidden_based_on_permissions(): void
{
$this->seed(\Database\Seeders\PermissionSeeder::class);
// Create a role with ONLY view-pages permission
$role = Role::create([
'name' => 'Page Viewer',
'slug' => 'page-viewer',
]);
$permission = Permission::where('slug', 'view-pages')->first();
$role->permissions()->attach($permission->id);
$user = User::factory()->create();
$user->roles()->attach($role);
$adminPath = env('ADMIN_PATH', 'loom');
$response = $this->actingAs($user)->get('/' . $adminPath);
$response->assertStatus(200);
// Verify "Pages" is visible in navigation
$response->assertSee('Pages');
$response->assertSee('file icon');
// Verify "Users", "Themes", "Backups", "Navigation" are NOT visible in navigation
$response->assertDontSee('Users');
$response->assertDontSee('Themes');
$response->assertDontSee('Backups');
$response->assertDontSee('Navigation');
// Verify Dashboard cards visibility (Svelte component data)
// Check for the data-permissions attribute in the dashboard view
$response->assertSee('data-permissions');
$response->assertSee('view-pages', false);
$response->assertSee('true', false);
$response->assertSee('view-themes', false);
$response->assertSee('false', false);
}
public function test_admin_sees_all_cards_in_dashboard_data(): void
{
$this->seed(\Database\Seeders\PermissionSeeder::class);
$this->seed(\Database\Seeders\RoleSeeder::class);
$user = User::factory()->create();
$user->roles()->attach(Role::where('slug', 'admin')->first());
$adminPath = env('ADMIN_PATH', 'loom');
$response = $this->actingAs($user)->get('/' . $adminPath);
$response->assertStatus(200);
// All permissions should be true for admin in data-permissions attribute
$response->assertSee('data-permissions');
$response->assertSee('&quot;view-pages&quot;:true', false);
$response->assertSee('&quot;view-themes&quot;:true', false);
$response->assertSee('&quot;view-users&quot;:true', false);
$response->assertSee('&quot;view-roles&quot;:true', false);
$response->assertSee('&quot;manage-settings&quot;:true', false);
}
public function test_media_manager_buttons_visibility_based_on_permissions(): void
{
$this->seed(\Database\Seeders\PermissionSeeder::class);
// Create a role with view-media but NO upload-media or delete-media
$role = Role::create([
'name' => 'Media Viewer',
'slug' => 'media-viewer',
]);
$role->permissions()->attach(Permission::where('slug', 'view-media')->first()->id);
$user = User::factory()->create();
$user->roles()->attach($role);
$adminPath = env('ADMIN_PATH', 'loom');
$response = $this->actingAs($user)->get('/' . $adminPath . '/media');
$response->assertStatus(200);
// Verify "upload-media" is false in Svelte component data
$response->assertSee('&quot;upload-media&quot;:false', false);
$response->assertSee('&quot;delete-media&quot;:false', false);
$response->assertSee('&quot;update-media&quot;:false', false);
// Verify "view-media" is true
$response->assertSee('&quot;view-media&quot;:true', false);
// Create a role with upload-media
$role2 = Role::create([
'name' => 'Media Creator',
'slug' => 'media-creator',
]);
$role2->permissions()->attach(Permission::where('slug', 'view-media')->first()->id);
$role2->permissions()->attach(Permission::where('slug', 'upload-media')->first()->id);
$user2 = User::factory()->create();
$user2->roles()->attach($role2);
$response = $this->actingAs($user2)->get('/' . $adminPath . '/media');
$response->assertStatus(200);
$response->assertSee('&quot;upload-media&quot;:true', false);
$response->assertSee('&quot;delete-media&quot;:false', false);
}
public function test_page_editor_passes_media_permissions_to_picker(): void
{
$this->seed(\Database\Seeders\PermissionSeeder::class);
$role = Role::create([
'name' => 'Page Editor Limited',
'slug' => 'page-editor-limited',
]);
$role->permissions()->attach(Permission::where('slug', 'view-pages')->first()->id);
$role->permissions()->attach(Permission::where('slug', 'create-pages')->first()->id);
$role->permissions()->attach(Permission::where('slug', 'edit-pages')->first()->id);
// NO media permissions
$user = User::factory()->create();
$user->roles()->attach($role);
$adminPath = env('ADMIN_PATH', 'loom');
$response = $this->actingAs($user)->get('/' . $adminPath . '/pages/create');
$response->assertStatus(200);
// Verify "upload-media" is false in data-permissions
$response->assertSee('data-permissions');
$response->assertSee('&quot;upload-media&quot;:false', false);
// Grant upload-media
$role->permissions()->attach(Permission::where('slug', 'upload-media')->first()->id);
$response = $this->actingAs($user)->get('/' . $adminPath . '/pages/create');
$response->assertStatus(200);
$response->assertSee('&quot;upload-media&quot;:true', false);
}
}