AdminListAccountTest.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Services\BackflowService;
  4. use App\Services\RebateService;
  5. use App\Services\RechargeService;
  6. use Illuminate\Config\Repository;
  7. use Illuminate\Database\Capsule\Manager;
  8. use Illuminate\Database\Schema\Blueprint;
  9. use Illuminate\Foundation\Application;
  10. use Illuminate\Support\Facades\DB;
  11. use Illuminate\Support\Facades\Facade;
  12. use PHPUnit\Framework\TestCase;
  13. /** 后台列表返回会员账号 account,并支持按 account 模糊筛选(关联查询与 join 查询两种写法)。 */
  14. class AdminListAccountTest extends TestCase
  15. {
  16. protected function setUp(): void
  17. {
  18. parent::setUp();
  19. Facade::clearResolvedInstances();
  20. $app = new Application(dirname(__DIR__, 2));
  21. $app->instance('config', new Repository(['app' => ['timezone' => 'Asia/Shanghai', 'url' => 'http://x']]));
  22. Facade::setFacadeApplication($app);
  23. $db = new Manager($app);
  24. $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']);
  25. $db->setAsGlobal();
  26. $db->bootEloquent();
  27. $app->instance('db', $db->getDatabaseManager());
  28. $app->bind('db.schema', fn () => $db->schema());
  29. $schema = $db->schema();
  30. $schema->create('users', function (Blueprint $t) {
  31. $t->id(); $t->string('member_id'); $t->string('account')->nullable(); $t->string('username')->nullable();
  32. $t->string('first_name')->nullable(); $t->string('admin_note')->nullable(); $t->integer('status')->default(0);
  33. $t->string('phone')->nullable(); $t->string('visitor_id')->nullable(); $t->string('register_ip')->nullable(); $t->timestamps();
  34. });
  35. $schema->create('rebates', function (Blueprint $t) {
  36. $t->id(); $t->string('member_id'); $t->date('date'); $t->integer('status')->default(0);
  37. $t->decimal('betting_amount', 20, 2)->default(0); $t->timestamps();
  38. });
  39. $schema->create('backflow', function (Blueprint $t) {
  40. $t->id(); $t->string('member_id'); $t->string('date'); $t->integer('status')->default(0); $t->timestamps();
  41. });
  42. $schema->create('recharges', function (Blueprint $t) {
  43. $t->id(); $t->string('member_id'); $t->string('coin')->default('CNY'); $t->decimal('amount', 20, 2)->default(0);
  44. $t->integer('status')->default(0); $t->timestamps();
  45. });
  46. DB::table('users')->insert([
  47. ['member_id' => 'm1', 'account' => 'alice'],
  48. ['member_id' => 'm2', 'account' => 'bob'],
  49. ['member_id' => 'm3', 'account' => null],
  50. ]);
  51. }
  52. protected function tearDown(): void
  53. {
  54. DB::disconnect();
  55. Facade::clearResolvedInstances();
  56. parent::tearDown();
  57. }
  58. public function test_rebate_list_shows_and_filters_account(): void
  59. {
  60. foreach (['m1', 'm2', 'm3'] as $m) {
  61. DB::table('rebates')->insert(['member_id' => $m, 'date' => '2026-01-01']);
  62. }
  63. $rows = $this->accounts(RebateService::paginate(['limit' => 10])['data']);
  64. $this->assertSame(['m1' => 'alice', 'm2' => 'bob', 'm3' => ''], $rows);
  65. $this->assertSame(['m1' => 'alice'], $this->accounts(RebateService::paginate(['account' => 'lic'])['data']));
  66. $this->assertSame(0, RebateService::paginate(['account' => 'nobody'])['total']);
  67. }
  68. public function test_rebate_list_shows_the_current_day_but_only_past_unpaid_days_can_be_granted(): void
  69. {
  70. \Carbon\Carbon::setTestNow(\Carbon\Carbon::parse('2026-11-05 15:00:00', 'Asia/Shanghai')); // 纽约 2026-11-05 02:00
  71. try {
  72. DB::table('rebates')->insert([
  73. ['member_id' => 'm1', 'date' => '2026-11-05', 'status' => 0],
  74. ['member_id' => 'm2', 'date' => '2026-11-04', 'status' => 0],
  75. ['member_id' => 'm3', 'date' => '2026-11-04', 'status' => 1],
  76. ]);
  77. $rows = [];
  78. foreach (json_decode(json_encode(RebateService::paginate(['limit' => 10])['data']), true) as $row) {
  79. $rows[$row['member_id']] = [$row['date'], $row['can_grant']];
  80. }
  81. $this->assertSame(['m1' => ['2026-11-05', false], 'm2' => ['2026-11-04', true], 'm3' => ['2026-11-04', false]], $rows);
  82. } finally {
  83. \Carbon\Carbon::setTestNow();
  84. }
  85. }
  86. public function test_backflow_list_shows_and_filters_account(): void
  87. {
  88. foreach (['m1', 'm2'] as $m) {
  89. DB::table('backflow')->insert(['member_id' => $m, 'date' => '2026-01']);
  90. }
  91. $this->assertSame(['m1' => 'alice', 'm2' => 'bob'], $this->accounts(BackflowService::paginate(['limit' => 10])['data']));
  92. $this->assertSame(['m2' => 'bob'], $this->accounts(BackflowService::paginate(['limit' => 10, 'account' => 'bo'])['data']));
  93. }
  94. public function test_recharge_list_shows_and_filters_account(): void
  95. {
  96. foreach (['m1', 'm2'] as $m) {
  97. DB::table('recharges')->insert(['member_id' => $m, 'amount' => 1, 'created_at' => '2026-01-01 00:00:00']);
  98. }
  99. $this->assertSame(['m1' => 'alice', 'm2' => 'bob'], $this->accounts(RechargeService::paginate([])['data']));
  100. $this->assertSame(['m1' => 'alice'], $this->accounts(RechargeService::paginate(['account' => 'ALI'])['data']));
  101. }
  102. private function accounts(array $rows): array
  103. {
  104. $out = [];
  105. foreach (json_decode(json_encode($rows), true) as $row) {
  106. $out[$row['member_id']] = $row['account'];
  107. }
  108. ksort($out);
  109. return $out;
  110. }
  111. }