create(); [$event, $run] = $this->createActiveRun(); HolidayClaim::create([ 'event_id' => $event->id, 'run_id' => $run->id, 'user_id' => $user->id, 'amount' => 500, 'claimed_at' => null, ]); $response = $this->actingAs($user)->getJson(route('holiday.status', ['run' => $run->id])); $response->assertOk(); $response->assertJson([ 'claimable' => true, 'claimed' => false, 'amount' => 500, 'status' => 'active', ]); } /** * 方法功能:验证用户领取批次福利后会入账并写回领取状态。 */ public function test_can_claim_holiday_bonus_from_run(): void { $user = User::factory()->create(['jjb' => 100]); [$event, $run] = $this->createActiveRun(); HolidayClaim::create([ 'event_id' => $event->id, 'run_id' => $run->id, 'user_id' => $user->id, 'amount' => 500, 'claimed_at' => null, ]); $response = $this->actingAs($user)->postJson(route('holiday.claim', ['run' => $run->id])); $response->assertOk(); $response->assertJson([ 'ok' => true, 'amount' => 500, ]); $this->assertSame(600, (int) $user->fresh()->jjb); $this->assertDatabaseHas('holiday_claims', [ 'event_id' => $event->id, 'run_id' => $run->id, 'user_id' => $user->id, 'amount' => 500, ]); $claimedRow = HolidayClaim::query() ->where('run_id', $run->id) ->where('user_id', $user->id) ->first(); $this->assertNotNull($claimedRow?->claimed_at); $this->assertSame('completed', $run->fresh()?->status); $this->assertSame(1, (int) $run->fresh()?->claimed_count); $this->assertSame(500, (int) $run->fresh()?->claimed_amount); } /** * 方法功能:验证不在批次名单中的用户不能领取福利。 */ public function test_cannot_claim_if_not_in_run_list(): void { $user = User::factory()->create(); [, $run] = $this->createActiveRun(); $response = $this->actingAs($user)->postJson(route('holiday.claim', ['run' => $run->id])); $response->assertOk(); $response->assertJson([ 'ok' => false, 'message' => '您不在本次福利名单内,或活动已结束。', ]); } /** * 方法功能:验证已过期批次会拒绝领取。 */ public function test_cannot_claim_if_run_is_expired(): void { $user = User::factory()->create(); [$event, $run] = $this->createActiveRun([ 'status' => 'expired', 'expires_at' => now()->subDay(), ]); HolidayClaim::create([ 'event_id' => $event->id, 'run_id' => $run->id, 'user_id' => $user->id, 'amount' => 500, 'claimed_at' => null, ]); $response = $this->actingAs($user)->postJson(route('holiday.claim', ['run' => $run->id])); $response->assertOk(); $response->assertJson([ 'ok' => false, 'message' => '活动已结束或已过期。', ]); } /** * 方法功能:创建一个默认可领取的节日福利模板与发放批次。 * * @param array $runOverrides * @return array{0: HolidayEvent, 1: HolidayEventRun} */ private function createActiveRun(array $runOverrides = []): array { $event = HolidayEvent::create([ 'name' => '元旦快乐', 'description' => '测试节日福利模板', 'status' => 'pending', 'enabled' => true, 'expires_at' => null, 'max_claimants' => 10, 'claimed_amount' => 0, 'claimed_count' => 0, 'total_amount' => 5000, 'min_amount' => 100, 'max_amount' => 1000, 'fixed_amount' => 500, 'distribute_type' => 'fixed', 'expire_minutes' => 30, 'send_at' => now(), 'repeat_type' => 'once', 'target_type' => 'all', ]); $run = HolidayEventRun::create(array_merge([ 'holiday_event_id' => $event->id, 'event_name' => $event->name, 'event_description' => $event->description, 'total_amount' => $event->total_amount, 'max_claimants' => $event->max_claimants, 'distribute_type' => $event->distribute_type, 'min_amount' => $event->min_amount, 'max_amount' => $event->max_amount, 'fixed_amount' => $event->fixed_amount, 'target_type' => $event->target_type, 'target_value' => null, 'repeat_type' => $event->repeat_type, 'scheduled_for' => now(), 'triggered_at' => now(), 'expires_at' => now()->addDay(), 'status' => 'active', 'audience_count' => 0, 'claimed_count' => 0, 'claimed_amount' => 0, ], $runOverrides)); return [$event, $run]; } }