doge 1 روز پیش
والد
کامیت
30efa8f5c8

+ 24 - 0
tests/Integration/AutomaticRewardGrantTest.php

@@ -234,6 +234,30 @@ class AutomaticRewardGrantTest extends TestCase
         return $cases;
     }
 
+    public function test_melbet_message_lists_returns_the_rebate_and_backflow_notices(): void
+    {
+        $rebate = $this->rebate(); $backflow = $this->backflow();
+        Schema::table('users', function (Blueprint $t) { $t->string('user_id')->nullable(); $t->dateTime('delete_time')->nullable(); });
+        DB::table('users')->where('member_id', '1001')->update(['user_id' => 'login-1001', 'language' => 'en']);
+        RewardGrantService::grant('rebate', $rebate, 'operator-one');
+        RewardGrantService::grant('backflow', $backflow, 'operator-one');
+        $snapshot = tempnam(sys_get_temp_dir(), 'reward-inbox-');
+        unlink($snapshot); // VACUUM INTO requires a new file.
+        try {
+            DB::statement('VACUUM INTO ?', [$snapshot]);
+            $probe = new \Symfony\Component\Process\Process([PHP_BINARY, '-d', 'xdebug.mode=off', dirname(__DIR__) . '/fixtures/reward_message_inbox_probe.php', $snapshot, 'login-1001']);
+            $probe->mustRun();
+            $result = json_decode($probe->getOutput(), true, 512, JSON_THROW_ON_ERROR);
+            $this->assertSame(2, $result['listing']['count']);
+            $this->assertEqualsCanonicalizing(['Bet rebate credited', 'Loss rebate credited'], array_column($result['listing']['list'], 'title'));
+            $this->assertSame(['en', 'en'], array_column($result['listing']['list'], 'language'));
+            $this->assertSame([false, false], array_column($result['listing']['list'], 'is_read'));
+            $this->assertCount(2, $result['details']);
+        } finally {
+            if (is_file($snapshot)) unlink($snapshot);
+        }
+    }
+
     public function test_message_failure_rolls_back_the_payout_and_retry_delivers_once(): void
     {
         $id = $this->rebate(); $this->enable('rebate');

+ 2 - 0
tests/Regression/yuebao_available_interest.php

@@ -82,6 +82,8 @@ namespace {
     check((int)\think\facade\Db::table('bot_activity_rewards')->where('id', 10)->value('rewarded_count') === 1, 'Automatic expiry records first distinct winner');
     $firstNotice = \app\api\service\MessageService::detail('1001', 1, 'zh');
     check($firstNotice['language'] === 'vi' && $firstNotice['title'] === 'Lãi Yuebao đã được ghi có' && str_contains($firstNotice['content'], '1.00'), 'Expiry notice uses users.language, regardless of request language');
+    $firstListing = \app\api\service\MessageService::lists('1001', ['category' => 'internal'], 'zh');
+    check($firstListing['count'] === 1 && $firstListing['list'][0]['title'] === 'Lãi Yuebao đã được ghi có', 'The actual message/lists query returns the interest notice');
     check((int)\think\facade\Db::table('bot_site_message_recipients')->value('recipient_id') === 1, 'Notice belongs to users.id, not user_id or member_id');
     $invest->invoke($command);
     check(\think\facade\Db::table('bot_yuebao_log')->count() === 1, 'Repeated expiry does not duplicate settlement');

+ 14 - 0
tests/fixtures/reward_message_inbox_probe.php

@@ -0,0 +1,14 @@
+<?php
+
+// Read a disposable SQLite snapshot through the site's actual /api/message/lists service.
+$repo = getenv('ACTIVITY_SITE_REPO') ?: dirname(__DIR__, 3) . '/melbet_sport-api';
+require $repo . '/vendor/autoload.php';
+$db = new \think\DbManager();
+$db->setConfig(['default' => 'sqlite', 'connections' => ['sqlite' => [
+    'type' => 'sqlite', 'database' => $argv[1], 'prefix' => '', 'fields_strict' => false,
+]], 'auto_timestamp' => false]);
+\think\Container::getInstance()->instance(\think\DbManager::class, $db);
+$listing = \app\api\service\MessageService::lists($argv[2], ['category' => 'internal'], 'vi');
+$details = [];
+foreach ($listing['list'] as $item) $details[] = \app\api\service\MessageService::detail($argv[2], $item['id'], 'vi');
+echo json_encode(['listing' => $listing, 'details' => $details], JSON_THROW_ON_ERROR);