ManualAuditAccountTest.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Services\ManualAuditService;
  4. use Illuminate\Config\Repository;
  5. use Illuminate\Database\Capsule\Manager;
  6. use Illuminate\Database\Schema\Blueprint;
  7. use Illuminate\Foundation\Application;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Facade;
  10. use PHPUnit\Framework\TestCase;
  11. /** Manual credit accepts member_id and/or account, and list rows show the member's account. */
  12. class ManualAuditAccountTest extends TestCase
  13. {
  14. protected function setUp(): void
  15. {
  16. parent::setUp();
  17. Facade::clearResolvedInstances();
  18. $app = new Application(dirname(__DIR__, 2));
  19. $app->instance('config', new Repository(['app' => ['timezone' => 'Asia/Shanghai']]));
  20. Facade::setFacadeApplication($app);
  21. $db = new Manager($app);
  22. $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']);
  23. $db->setAsGlobal();
  24. $db->bootEloquent();
  25. $app->instance('db', $db->getDatabaseManager());
  26. $app->bind('db.schema', fn () => $db->schema());
  27. $db->schema()->create('users', function (Blueprint $t) {
  28. $t->id(); $t->string('member_id'); $t->string('account')->nullable(); $t->timestamps();
  29. });
  30. $db->schema()->create('manual_audits', function (Blueprint $t) {
  31. $t->id(); $t->string('request_id'); $t->string('request_hash'); $t->integer('admin_id')->nullable();
  32. $t->integer('balance_log_id')->nullable(); $t->string('member_id'); $t->string('username')->default('');
  33. $t->string('first_name')->default(''); $t->string('transaction_type'); $t->string('change_type');
  34. $t->decimal('amount', 30, 10); $t->decimal('before_balance', 30, 10)->nullable(); $t->decimal('after_balance', 30, 10)->nullable();
  35. $t->integer('level_before')->default(0); $t->string('level_before_name')->default(''); $t->integer('level_after')->default(0);
  36. $t->string('level_after_name')->default(''); $t->integer('status')->default(0); $t->string('remark')->default('');
  37. $t->string('failure_reason')->default(''); $t->timestamps();
  38. });
  39. DB::table('users')->insert([
  40. ['member_id' => 'm1', 'account' => 'alice'],
  41. ['member_id' => 'm2', 'account' => 'dup'],
  42. ['member_id' => 'm3', 'account' => 'dup'],
  43. ]);
  44. }
  45. protected function tearDown(): void
  46. {
  47. DB::disconnect();
  48. Facade::clearResolvedInstances();
  49. parent::tearDown();
  50. }
  51. public function test_member_id_and_account_resolve_to_one_member(): void
  52. {
  53. $this->assertSame('m1', ManualAuditService::resolveMemberId('m1', null));
  54. $this->assertSame('m1', ManualAuditService::resolveMemberId(null, 'alice'));
  55. $this->assertSame('m1', ManualAuditService::resolveMemberId(' m1 ', ' alice '));
  56. $this->assertResolveFails('m2', 'alice', '会员ID与账号不一致');
  57. $this->assertResolveFails(null, 'nobody', '账号不存在');
  58. $this->assertResolveFails(null, 'dup', '对应多个会员');
  59. $this->assertResolveFails('', '', '请填写会员ID或账号');
  60. }
  61. public function test_list_and_detail_return_the_member_account(): void
  62. {
  63. foreach (['m1', 'm9'] as $i => $memberId) {
  64. DB::table('manual_audits')->insert(['request_id' => "r{$i}", 'request_hash' => 'h', 'member_id' => $memberId,
  65. 'transaction_type' => 'credit', 'change_type' => '人工充值', 'amount' => 10, 'status' => 1, 'created_at' => '2026-11-04 12:00:00']);
  66. }
  67. $rows = array_column(ManualAuditService::list([])['data'], 'account', 'member_id');
  68. $this->assertSame(['m9' => '', 'm1' => 'alice'], $rows);
  69. $this->assertSame('alice', ManualAuditService::detail(1)['account']);
  70. }
  71. private function assertResolveFails(?string $memberId, ?string $account, string $message): void
  72. {
  73. try {
  74. ManualAuditService::resolveMemberId($memberId, $account);
  75. $this->fail('Expected failure: ' . $message);
  76. } catch (\Exception $e) {
  77. $this->assertStringContainsString($message, $e->getMessage());
  78. }
  79. }
  80. }