'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, ]); } }