'Super Admin']); Role::firstOrCreate(['name' => 'admin']); Role::firstOrCreate(['name' => 'Project Manager']); Role::firstOrCreate(['name' => 'Main Contractor Admin']); Role::firstOrCreate(['name' => 'Construction Supervisor']); Role::firstOrCreate(['name' => 'Site Technical']); $this->contractor = Contractor::create([ 'company_name' => 'Apex Builders Inc', 'contact_person' => 'John Apex', 'email' => 'apex@contractor.test', 'status' => 'active', ]); $permUsers = \Spatie\Permission\Models\Permission::firstOrCreate(['name' => 'users.access']); $this->superAdmin = User::factory()->create(['user_type' => 'admin', 'email_verified_at' => now()]); $this->superAdmin->assignRole('Super Admin'); $this->superAdmin->givePermissionTo($permUsers); $this->admin = User::factory()->create(['user_type' => 'admin', 'email_verified_at' => now()]); $this->admin->assignRole('admin'); $this->admin->givePermissionTo($permUsers); $this->contractorAdmin = User::factory()->create([ 'user_type' => 'contractor', 'contractor_id' => $this->contractor->id, 'email_verified_at' => now(), ]); $this->contractorAdmin->assignRole('Main Contractor Admin'); $this->contractorAdmin->givePermissionTo($permUsers); } public function test_contractor_admin_can_create_user_with_permitted_roles(): void { $permittedRoles = [ 'Main Contractor Admin', 'Construction Supervisor', 'Site Technical', ]; foreach ($permittedRoles as $idx => $role) { $userType = $role === 'Main Contractor Admin' ? 'contractor' : 'employee'; $response = $this->actingAs($this->contractorAdmin)->post(route('users.store'), [ 'name' => "Permitted User {$idx}", 'email' => "permitted{$idx}@contractor.test", 'user_type' => $userType, 'status' => 'active', 'auto_password' => true, 'spatie_role' => $role, ]); $response->assertRedirect(); $this->assertDatabaseHas('users', [ 'email' => "permitted{$idx}@contractor.test", 'contractor_id' => $this->contractor->id, ]); $createdUser = User::where('email', "permitted{$idx}@contractor.test")->first(); $this->assertNotNull($createdUser); $this->assertTrue($createdUser->hasRole($role)); } } public function test_contractor_admin_cannot_escalate_user_to_super_admin(): void { $response = $this->actingAs($this->contractorAdmin)->post(route('users.store'), [ 'name' => 'Escalated Super Admin', 'email' => 'hacked.superadmin@test.com', 'user_type' => 'employee', 'status' => 'active', 'auto_password' => true, 'spatie_role' => 'Super Admin', ]); $response->assertSessionHasErrors('spatie_role'); $this->assertDatabaseMissing('users', [ 'email' => 'hacked.superadmin@test.com', ]); } public function test_contractor_admin_cannot_escalate_user_to_platform_admin(): void { $response = $this->actingAs($this->contractorAdmin)->post(route('users.store'), [ 'name' => 'Escalated Admin', 'email' => 'hacked.admin@test.com', 'user_type' => 'employee', 'status' => 'active', 'auto_password' => true, 'spatie_role' => 'admin', ]); $response->assertSessionHasErrors('spatie_role'); $this->assertDatabaseMissing('users', [ 'email' => 'hacked.admin@test.com', ]); } public function test_contractor_admin_cannot_escalate_user_to_project_manager(): void { $response = $this->actingAs($this->contractorAdmin)->post(route('users.store'), [ 'name' => 'Escalated PM', 'email' => 'hacked.pm@test.com', 'user_type' => 'employee', 'status' => 'active', 'auto_password' => true, 'spatie_role' => 'Project Manager', ]); $response->assertSessionHasErrors('spatie_role'); $this->assertDatabaseMissing('users', [ 'email' => 'hacked.pm@test.com', ]); } public function test_platform_super_admin_can_assign_any_role(): void { $allRoles = [ 'Super Admin', 'admin', 'Project Manager', 'Main Contractor Admin', 'Construction Supervisor', 'Site Technical', ]; foreach ($allRoles as $idx => $role) { $userType = match ($role) { 'Super Admin', 'admin' => 'admin', 'Main Contractor Admin' => 'contractor', default => 'employee', }; $response = $this->actingAs($this->superAdmin)->post(route('users.store'), [ 'name' => "Admin Assigned {$idx}", 'email' => "platform_created_{$idx}@test.com", 'user_type' => $userType, 'status' => 'active', 'auto_password' => true, 'spatie_role' => $role, ]); $response->assertRedirect(); $this->assertDatabaseHas('users', [ 'email' => "platform_created_{$idx}@test.com", ]); $created = User::where('email', "platform_created_{$idx}@test.com")->first(); $this->assertTrue($created->hasRole($role)); } } }