167 lines
5.8 KiB
PHP
167 lines
5.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function (): void {
|
|
config()->set('database.connections.legacy', config('database.connections.' . config('database.default')));
|
|
DB::purge('legacy');
|
|
|
|
Schema::connection('legacy')->dropIfExists('legacy_users');
|
|
Schema::connection('legacy')->create('legacy_users', function (Blueprint $table): void {
|
|
$table->unsignedBigInteger('user_id')->primary();
|
|
$table->string('uname')->nullable();
|
|
$table->string('email')->nullable();
|
|
$table->string('real_name')->nullable();
|
|
$table->timestamp('joinDate')->nullable();
|
|
$table->timestamp('LastVisit')->nullable();
|
|
$table->unsignedTinyInteger('active')->default(1);
|
|
$table->unsignedTinyInteger('should_migrate')->default(0);
|
|
});
|
|
});
|
|
|
|
afterEach(function (): void {
|
|
Schema::connection('legacy')->dropIfExists('legacy_users');
|
|
});
|
|
|
|
it('passes when every legacy should_migrate user exists in the new users table', function (): void {
|
|
DB::table('users')->insert([
|
|
[
|
|
'id' => 101,
|
|
'username' => 'alpha',
|
|
'email' => 'alpha@example.test',
|
|
'password' => bcrypt('secret'),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
],
|
|
[
|
|
'id' => 102,
|
|
'username' => 'beta',
|
|
'email' => 'beta@example.test',
|
|
'password' => bcrypt('secret'),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
],
|
|
]);
|
|
|
|
DB::connection('legacy')->table('legacy_users')->insert([
|
|
['user_id' => 101, 'uname' => 'alpha', 'email' => 'alpha@example.test', 'should_migrate' => 1],
|
|
['user_id' => 102, 'uname' => 'beta', 'email' => 'beta@example.test', 'should_migrate' => 1],
|
|
['user_id' => 103, 'uname' => 'gamma', 'email' => 'gamma@example.test', 'should_migrate' => 0],
|
|
]);
|
|
|
|
$code = Artisan::call('users:audit-missing-migrated', [
|
|
'--legacy-users-table' => 'legacy_users',
|
|
'--chunk' => 1,
|
|
]);
|
|
|
|
$output = Artisan::output();
|
|
|
|
expect($code)->toBe(0)
|
|
->and($output)->toContain('Scanning legacy.legacy_users for should_migrate=1 and checking')
|
|
->and($output)->toContain('Done. scanned=2 existing=2 missing=0')
|
|
->and($output)->not->toContain('[missing]');
|
|
});
|
|
|
|
it('fails and outputs legacy users that are missing in the new users table', function (): void {
|
|
DB::table('users')->insert([
|
|
'id' => 201,
|
|
'username' => 'present-user',
|
|
'email' => 'present@example.test',
|
|
'password' => bcrypt('secret'),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
DB::connection('legacy')->table('legacy_users')->insert([
|
|
['user_id' => 201, 'uname' => 'present-user', 'email' => 'present@example.test', 'should_migrate' => 1],
|
|
['user_id' => 202, 'uname' => 'missing-user', 'email' => 'missing@example.test', 'should_migrate' => 1],
|
|
['user_id' => 203, 'uname' => null, 'email' => null, 'should_migrate' => 1],
|
|
]);
|
|
|
|
$code = Artisan::call('users:audit-missing-migrated', [
|
|
'--legacy-users-table' => 'legacy_users',
|
|
'--chunk' => 2,
|
|
]);
|
|
|
|
$output = Artisan::output();
|
|
|
|
expect($code)->toBe(1)
|
|
->and($output)->toContain('[missing] id=202 uname=@missing-user email=<missing@example.test>')
|
|
->and($output)->toContain('[missing] id=203 uname=(none) email=(none)')
|
|
->and($output)->toContain('Done. scanned=3 existing=1 missing=2');
|
|
});
|
|
|
|
it('can write missing users to a transaction wrapped sql file', function (): void {
|
|
$sqlPath = base_path('test-results/audit-missing-migrated-users.sql');
|
|
@unlink($sqlPath);
|
|
|
|
DB::table('users')->insert([
|
|
[
|
|
'id' => 301,
|
|
'username' => 'present-user',
|
|
'email' => 'present@example.test',
|
|
'password' => bcrypt('secret'),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
],
|
|
[
|
|
'id' => 999,
|
|
'username' => 'missing-user',
|
|
'email' => 'missing@example.test',
|
|
'password' => bcrypt('secret'),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
],
|
|
]);
|
|
|
|
DB::connection('legacy')->table('legacy_users')->insert([
|
|
[
|
|
'user_id' => 301,
|
|
'uname' => 'present-user',
|
|
'email' => 'present@example.test',
|
|
'real_name' => 'Present User',
|
|
'joinDate' => '2024-01-01 10:00:00',
|
|
'LastVisit' => '2024-01-02 11:00:00',
|
|
'active' => 1,
|
|
'should_migrate' => 1,
|
|
],
|
|
[
|
|
'user_id' => 302,
|
|
'uname' => 'missing-user',
|
|
'email' => 'missing@example.test',
|
|
'real_name' => 'Legacy Missing',
|
|
'joinDate' => '2023-05-01 08:30:00',
|
|
'LastVisit' => '2023-05-03 09:45:00',
|
|
'active' => 0,
|
|
'should_migrate' => 1,
|
|
],
|
|
]);
|
|
|
|
$code = Artisan::call('users:audit-missing-migrated', [
|
|
'--legacy-users-table' => 'legacy_users',
|
|
'--sql-output' => $sqlPath,
|
|
]);
|
|
|
|
$output = Artisan::output();
|
|
$sql = file_get_contents($sqlPath);
|
|
|
|
expect($code)->toBe(1)
|
|
->and($output)->toContain('SQL export written to ' . $sqlPath . ' with 1 INSERT statement(s).')
|
|
->and($sql)->not->toBeFalse()
|
|
->and($sql)->toContain('START TRANSACTION;')
|
|
->and($sql)->toContain('INSERT INTO `users`')
|
|
->and($sql)->toContain("302, 'tmpu302'")
|
|
->and($sql)->toContain("'missing+1@example.test'")
|
|
->and($sql)->toContain("'Legacy Missing'")
|
|
->and($sql)->toContain('COMMIT;');
|
|
|
|
@unlink($sqlPath);
|
|
}); |