feat: add routes, lang, tests, stubs, docs, and docker configurations
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Models\PasswordHistory;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Role;
|
||||
use App\Models\User;
|
||||
use App\Models\UserConsent;
|
||||
use App\Models\UserTrustedDevice;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
test('force deleting a user cascades password_histories', function () {
|
||||
$user = User::factory()->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);
|
||||
});
|
||||
Reference in New Issue
Block a user