extend(TestCase::class) // ->use(RefreshDatabase::class) ->in('Feature'); pest()->extend(TestCase::class)->in('Unit'); /* |-------------------------------------------------------------------------- | Expectations |-------------------------------------------------------------------------- | | When you're writing tests, you often need to check that values meet certain conditions. The | "expect()" function gives you access to a set of "expectations" methods that you can use | to assert different things. Of course, you may extend the Expectation API at any time. | */ expect()->extend('toBeOne', function () { return $this->toBe(1); }); /* |-------------------------------------------------------------------------- | Functions |-------------------------------------------------------------------------- | | While Pest is very powerful out-of-the-box, you may have some testing code specific to your | project that you don't want to repeat in every file. Here you can also expose helpers as | global functions to help you to reduce the number of lines of code in your test files. | */ /** 为后台测试账号挂上唯一超级管理员(不绑定站点)。 */ function grantSuperAdminRole(AdminUser $admin): void { \App\Support\PlatformSystemRoles::ensureSuperAdminRole(); \App\Support\SuperAdminAccount::assign($admin); } /** 为后台测试账号挂上代理节点(需已存在 agent_nodes / admin_user_agents 表)。 */ /** Feature 测直调 {@see AgentNodeService::createChild()} 时使用的密码。 */ function agentNodeTestPassword(): string { return '12345678'; } /** @param array $overrides * @return array */ function agentChildPayload(array $overrides = []): array { return array_merge([ 'password' => agentNodeTestPassword(), 'can_create_child_agent' => true, 'can_create_player' => true, ], $overrides); } function bindAdminUserToAgent(AdminUser $admin, int $agentNodeId): void { DB::table('admin_user_agents')->updateOrInsert( ['admin_user_id' => $admin->id], [ 'agent_node_id' => $agentNodeId, 'is_primary' => true, 'granted_at' => now(), ], ); } /** 确保默认站点一级代理已有占成/授信档案(子代理创建与额度校验依赖)。 */ function ensureRootAgentProfileSeeded(): void { $rootId = DB::table('agent_nodes')->where('depth', 0)->value('id'); if ($rootId === null) { return; } \App\Models\AgentProfile::query()->updateOrCreate( ['agent_node_id' => (int) $rootId], [ 'total_share_rate' => 100, 'credit_limit' => 1_000_000, 'allocated_credit' => 0, 'used_credit' => 0, 'rebate_limit' => 1, 'default_player_rebate' => 0, ], ); } function ensureAdminActionCatalogSeeded(): void { if (! Schema::hasTable('admin_action_catalog')) { Schema::create('admin_action_catalog', static function ($table): void { $table->id(); $table->string('code')->unique(); $table->string('name'); $table->unsignedTinyInteger('status')->default(1); $table->timestamps(); }); } $now = Carbon::now(); foreach ([ ['code' => 'view', 'name' => '查看'], ['code' => 'manage', 'name' => '管理'], ] as $row) { DB::table('admin_action_catalog')->updateOrInsert( ['code' => $row['code']], [ 'name' => $row['name'], 'status' => 1, 'created_at' => $now, 'updated_at' => $now, ], ); } } /** * 返回项目内所有 Broadcast 事件类列表,供 Event::fake() 拦截广播使用。 * * 业务切到 reverb driver 后,fake 列表不全会导致未拦截的 broadcast 真实派发、 * 真实连接 Reverb/Pusher,CI 环境无可用 server 时直接 500。本 helper 保证: * Event::fake(allBroadcastEvents()) * 一行覆盖流程中可能触发的所有事件。 * * 不可使用 Event::fake() 无参形式:会同时拦截 Illuminate\Database\Events\* 等框架事件, * 干扰 RefreshDatabase / model events / 自定义 boot hooks。 * * @return list */ function allBroadcastEvents(): array { return [ \App\Events\BalanceUpdateBroadcast::class, \App\Events\DrawCountdownBroadcast::class, \App\Events\DrawResultPublishedBroadcast::class, \App\Events\DrawStatusChangeBroadcast::class, \App\Events\JackpotBurstBroadcast::class, \App\Events\OddsUpdateBroadcast::class, \App\Events\PlayCatalogUpdatedBroadcast::class, \App\Events\PlayToggleBroadcast::class, \App\Events\RiskSoldOutBroadcast::class, \App\Events\RiskWarningBroadcast::class, ]; }