|
@@ -0,0 +1,81 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+namespace Tests\Integration;
|
|
|
|
|
+
|
|
|
|
|
+use App\Console\Commands\FillTelegramAccounts;
|
|
|
|
|
+use App\Models\User;
|
|
|
|
|
+use Illuminate\Config\Repository;
|
|
|
|
|
+use Illuminate\Database\Capsule\Manager;
|
|
|
|
|
+use Illuminate\Database\Schema\Blueprint;
|
|
|
|
|
+use Illuminate\Foundation\Application;
|
|
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
|
|
+use Illuminate\Support\Facades\Facade;
|
|
|
|
|
+use PHPUnit\Framework\TestCase;
|
|
|
|
|
+use Symfony\Component\Console\Input\ArrayInput;
|
|
|
|
|
+use Symfony\Component\Console\Output\BufferedOutput;
|
|
|
|
|
+
|
|
|
|
|
+/** Telegram users (from=-1) get a unique tg+digits account; backfill only touches empty ones. */
|
|
|
|
|
+class TelegramAccountTest extends TestCase
|
|
|
|
|
+{
|
|
|
|
|
+ private Application $app;
|
|
|
|
|
+
|
|
|
|
|
+ protected function setUp(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ parent::setUp();
|
|
|
|
|
+ Facade::clearResolvedInstances();
|
|
|
|
|
+ $this->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());
|
|
|
|
|
+ }
|
|
|
|
|
+}
|