TelegramAccountTest.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Console\Commands\FillTelegramAccounts;
  4. use App\Models\User;
  5. use Illuminate\Config\Repository;
  6. use Illuminate\Database\Capsule\Manager;
  7. use Illuminate\Database\Schema\Blueprint;
  8. use Illuminate\Foundation\Application;
  9. use Illuminate\Support\Facades\DB;
  10. use Illuminate\Support\Facades\Facade;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\Console\Input\ArrayInput;
  13. use Symfony\Component\Console\Output\BufferedOutput;
  14. /** Telegram users (from=-1) get a unique tg+digits account; backfill only touches empty ones. */
  15. class TelegramAccountTest extends TestCase
  16. {
  17. private Application $app;
  18. protected function setUp(): void
  19. {
  20. parent::setUp();
  21. Facade::clearResolvedInstances();
  22. $this->app = $app = new Application(dirname(__DIR__, 2));
  23. $app->instance('config', new Repository(['app' => ['timezone' => 'Asia/Shanghai']]));
  24. Facade::setFacadeApplication($app);
  25. $db = new Manager($app);
  26. $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']);
  27. $db->setAsGlobal();
  28. $db->bootEloquent();
  29. $app->instance('db', $db->getDatabaseManager());
  30. $db->schema()->create('users', function (Blueprint $t) {
  31. $t->id(); $t->string('member_id'); $t->string('account')->nullable(); $t->integer('from')->default(0); $t->timestamps();
  32. });
  33. DB::table('users')->insert([
  34. ['member_id' => 't1', 'account' => null, 'from' => -1],
  35. ['member_id' => 't2', 'account' => '', 'from' => -1],
  36. ['member_id' => 't3', 'account' => 'keepme', 'from' => -1],
  37. ['member_id' => 'w1', 'account' => null, 'from' => 1],
  38. ]);
  39. }
  40. protected function tearDown(): void
  41. {
  42. DB::disconnect();
  43. Facade::clearResolvedInstances();
  44. parent::tearDown();
  45. }
  46. public function test_generated_account_format_and_skips_existing(): void
  47. {
  48. $account = User::generateTgAccount();
  49. $this->assertMatchesRegularExpression('/^tg\d{8}$/', $account);
  50. // 只有 1 位数字时空间只有 10 个,占掉 9 个后必须拿到剩下那个
  51. foreach (range(0, 8) as $d) DB::table('users')->insert(['member_id' => "x$d", 'account' => "tg$d"]);
  52. $this->assertSame('tg9', User::generateTgAccount(1));
  53. }
  54. public function test_backfill_only_fills_empty_telegram_accounts(): void
  55. {
  56. $this->runCommand(['--dry-run' => true]);
  57. $this->assertSame(2, DB::table('users')->where('from', -1)->where(fn ($q) => $q->whereNull('account')->orWhere('account', ''))->count());
  58. $this->runCommand([]);
  59. $rows = DB::table('users')->pluck('account', 'member_id');
  60. $this->assertMatchesRegularExpression('/^tg\d{8}$/', $rows['t1']);
  61. $this->assertMatchesRegularExpression('/^tg\d{8}$/', $rows['t2']);
  62. $this->assertNotSame($rows['t1'], $rows['t2']);
  63. $this->assertSame('keepme', $rows['t3']);
  64. $this->assertNull($rows['w1']);
  65. }
  66. private function runCommand(array $input): void
  67. {
  68. $command = new FillTelegramAccounts();
  69. $command->setLaravel($this->app);
  70. $command->run(new ArrayInput($input), new BufferedOutput());
  71. }
  72. }