You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.3 KiB
105 lines
3.3 KiB
|
2 days ago
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Feature;
|
||
|
|
|
||
|
|
use App\Models\User;
|
||
|
|
use Illuminate\Database\Schema\Blueprint;
|
||
|
|
use Illuminate\Support\Facades\DB;
|
||
|
|
use Illuminate\Support\Facades\Hash;
|
||
|
|
use Illuminate\Support\Facades\Schema;
|
||
|
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||
|
|
use Tests\TestCase;
|
||
|
|
|
||
|
|
class ResetVenueAdminPasswordsCommandTest extends TestCase
|
||
|
|
{
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
|
||
|
|
config([
|
||
|
|
'database.default' => 'sqlite',
|
||
|
|
'database.connections.sqlite.database' => ':memory:',
|
||
|
|
]);
|
||
|
|
DB::purge();
|
||
|
|
DB::reconnect();
|
||
|
|
|
||
|
|
Schema::create('users', function (Blueprint $table) {
|
||
|
|
$table->id();
|
||
|
|
$table->string('username')->nullable()->unique();
|
||
|
|
$table->string('name');
|
||
|
|
$table->string('email')->nullable();
|
||
|
|
$table->timestamp('email_verified_at')->nullable();
|
||
|
|
$table->string('password');
|
||
|
|
$table->string('role')->default('venue_admin');
|
||
|
|
$table->boolean('is_active')->default(true);
|
||
|
|
$table->rememberToken();
|
||
|
|
$table->timestamps();
|
||
|
|
});
|
||
|
|
|
||
|
|
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||
|
|
$table->id();
|
||
|
|
$table->morphs('tokenable');
|
||
|
|
$table->string('name');
|
||
|
|
$table->string('token', 64)->unique();
|
||
|
|
$table->text('abilities')->nullable();
|
||
|
|
$table->timestamp('last_used_at')->nullable();
|
||
|
|
$table->timestamp('expires_at')->nullable();
|
||
|
|
$table->timestamps();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_dry_run_does_not_change_password_or_tokens(): void
|
||
|
|
{
|
||
|
|
$user = $this->venueAdmin('old_admin');
|
||
|
|
$user->createToken('admin-token');
|
||
|
|
$oldHash = $user->password;
|
||
|
|
|
||
|
|
$this->artisan('venues:reset-admin-passwords', ['--dry-run' => true])
|
||
|
|
->assertSuccessful();
|
||
|
|
|
||
|
|
$fresh = $user->fresh();
|
||
|
|
$this->assertSame($oldHash, $fresh->password);
|
||
|
|
$this->assertSame(1, $fresh->tokens()->count());
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_reset_writes_new_hash_revokes_tokens_and_exports_xlsx(): void
|
||
|
|
{
|
||
|
|
$user = $this->venueAdmin('venue_one');
|
||
|
|
$user->createToken('admin-token');
|
||
|
|
$oldHash = $user->password;
|
||
|
|
|
||
|
|
$out = storage_path('app/exports/test_venue_admin_password_reset.xlsx');
|
||
|
|
if (is_file($out)) {
|
||
|
|
unlink($out);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->artisan('venues:reset-admin-passwords', ['--output' => $out])
|
||
|
|
->assertSuccessful();
|
||
|
|
|
||
|
|
$fresh = $user->fresh();
|
||
|
|
$this->assertNotSame($oldHash, $fresh->password);
|
||
|
|
$this->assertSame(0, $fresh->tokens()->count());
|
||
|
|
$this->assertFileExists($out);
|
||
|
|
|
||
|
|
$sheet = IOFactory::load($out)->getActiveSheet()->toArray();
|
||
|
|
$this->assertSame('venue_one', $sheet[1][2]);
|
||
|
|
$plain = (string) $sheet[1][3];
|
||
|
|
$this->assertGreaterThanOrEqual(12, strlen($plain));
|
||
|
|
$this->assertTrue(Hash::check($plain, $fresh->password));
|
||
|
|
|
||
|
|
unlink($out);
|
||
|
|
}
|
||
|
|
|
||
|
|
private function venueAdmin(string $username): User
|
||
|
|
{
|
||
|
|
return User::query()->create([
|
||
|
|
'username' => $username,
|
||
|
|
'name' => '场馆管理员',
|
||
|
|
'email' => $username.'@example.test',
|
||
|
|
'password' => 'OldPlace!holder1',
|
||
|
|
'role' => 'venue_admin',
|
||
|
|
'is_active' => true,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|