app = $app = new Application(dirname(__DIR__, 2)); $app->instance('config', new Repository(['app' => ['timezone' => 'Asia/Shanghai']])); Facade::setFacadeApplication($app); $db = new Manager($app); $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']); $db->setAsGlobal(); $db->bootEloquent(); $app->instance('db', $db->getDatabaseManager()); $db->schema()->create('users', function (Blueprint $t) { $t->id(); $t->string('member_id'); $t->string('account')->nullable(); $t->integer('from')->default(0); $t->timestamps(); }); DB::table('users')->insert([ ['member_id' => 't1', 'account' => null, 'from' => -1], ['member_id' => 't2', 'account' => '', 'from' => -1], ['member_id' => 't3', 'account' => 'keepme', 'from' => -1], ['member_id' => 'w1', 'account' => null, 'from' => 1], ]); } protected function tearDown(): void { DB::disconnect(); Facade::clearResolvedInstances(); parent::tearDown(); } public function test_generated_account_format_and_skips_existing(): void { $account = User::generateTgAccount(); $this->assertMatchesRegularExpression('/^tg\d{8}$/', $account); // 只有 1 位数字时空间只有 10 个,占掉 9 个后必须拿到剩下那个 foreach (range(0, 8) as $d) DB::table('users')->insert(['member_id' => "x$d", 'account' => "tg$d"]); $this->assertSame('tg9', User::generateTgAccount(1)); } public function test_backfill_only_fills_empty_telegram_accounts(): void { $this->runCommand(['--dry-run' => true]); $this->assertSame(2, DB::table('users')->where('from', -1)->where(fn ($q) => $q->whereNull('account')->orWhere('account', ''))->count()); $this->runCommand([]); $rows = DB::table('users')->pluck('account', 'member_id'); $this->assertMatchesRegularExpression('/^tg\d{8}$/', $rows['t1']); $this->assertMatchesRegularExpression('/^tg\d{8}$/', $rows['t2']); $this->assertNotSame($rows['t1'], $rows['t2']); $this->assertSame('keepme', $rows['t3']); $this->assertNull($rows['w1']); } private function runCommand(array $input): void { $command = new FillTelegramAccounts(); $command->setLaravel($this->app); $command->run(new ArrayInput($input), new BufferedOutput()); } }