create(); PasswordHistory::create(['user_id' => $user->id, 'password' => Hash::make('a')]); PasswordHistory::create(['user_id' => $user->id, 'password' => Hash::make('b')]); expect(PasswordHistory::where('user_id', $user->id)->count())->toBe(2); $user->forceDelete(); expect(PasswordHistory::where('user_id', $user->id)->count())->toBe(0); }); test('force deleting a user cascades user_consents', function () { $user = User::factory()->create(); UserConsent::create([ 'user_id' => $user->id, 'consent_type' => 'tos', 'version_id' => 1, 'ip_address' => '127.0.0.1', ]); expect(UserConsent::where('user_id', $user->id)->count())->toBe(1); $user->forceDelete(); expect(UserConsent::where('user_id', $user->id)->count())->toBe(0); }); test('force deleting a user cascades user_trusted_devices', function () { $user = User::factory()->create(); UserTrustedDevice::create([ 'user_id' => $user->id, 'device_id' => 'dev-1', 'token' => 'tok', 'expires_at' => now()->addDays(30), ]); $user->forceDelete(); expect(UserTrustedDevice::where('user_id', $user->id)->count())->toBe(0); }); test('force deleting a user nulls system_settings audit columns', function () { $actor = User::factory()->create(); DB::table('system_settings')->insert([ 'key' => 'cascade_test', 'value' => 'x', 'type' => 'string', 'group' => 'branding', 'is_public' => false, 'created_by' => $actor->id, 'updated_by' => $actor->id, 'created_at' => now(), 'updated_at' => now(), ]); $actor->forceDelete(); $row = DB::table('system_settings')->where('key', 'cascade_test')->first(); expect($row->created_by)->toBeNull(); expect($row->updated_by)->toBeNull(); }); test('force deleting a user nulls system_setting_revisions.changed_by', function () { $actor = User::factory()->create(); $settingId = DB::table('system_settings')->insertGetId([ 'key' => 'cascade_test_2', 'value' => 'x', 'type' => 'string', 'group' => 'branding', 'is_public' => false, 'created_at' => now(), 'updated_at' => now(), ]); DB::table('system_setting_revisions')->insert([ 'system_setting_id' => $settingId, 'key' => 'cascade_test_2', 'old_value' => null, 'new_value' => '"x"', 'changed_by' => $actor->id, 'created_at' => now(), ]); $actor->forceDelete(); expect(DB::table('system_setting_revisions')->where('key', 'cascade_test_2')->value('changed_by')) ->toBeNull(); }); test('deleting a role removes role_has_permissions linkage', function () { $role = Role::create(['name' => 'cascade-role', 'guard_name' => 'web']); $perm = Permission::firstOrCreate(['name' => 'cascade-perm', 'guard_name' => 'web']); $role->givePermissionTo($perm); expect(DB::table('role_has_permissions')->where('role_id', $role->id)->count())->toBe(1); $role->forceDelete(); expect(DB::table('role_has_permissions')->where('role_id', $role->id)->count())->toBe(0); }); test('deleting a permission removes role_has_permissions linkage', function () { $role = Role::create(['name' => 'host-role', 'guard_name' => 'web']); $perm = Permission::firstOrCreate(['name' => 'doomed-perm', 'guard_name' => 'web']); $role->givePermissionTo($perm); $perm->forceDelete(); expect(DB::table('role_has_permissions')->where('permission_id', $perm->id)->count())->toBe(0); }); test('roles audit columns null out when the actor is force-deleted', function () { $actor = User::factory()->create(); $role = Role::create(['name' => 'audit-role', 'guard_name' => 'web']); DB::table('roles')->where('id', $role->id)->update([ 'created_by' => $actor->id, 'updated_by' => $actor->id, ]); $actor->forceDelete(); $row = DB::table('roles')->where('id', $role->id)->first(); expect($row->created_by)->toBeNull(); expect($row->updated_by)->toBeNull(); }); test('soft-deleting a user keeps related rows intact', function () { $user = User::factory()->create(); PasswordHistory::create(['user_id' => $user->id, 'password' => Hash::make('a')]); $user->delete(); // soft expect(User::withTrashed()->find($user->id)->trashed())->toBeTrue(); expect(PasswordHistory::where('user_id', $user->id)->count())->toBe(1); });