create(); $activeItem = ShopItem::create([ 'name' => 'Active', 'slug' => 'active_item', 'type' => 'one_time', 'price' => 100, 'is_active' => true, ]); $inactiveItem = ShopItem::create([ 'name' => 'Inactive', 'slug' => 'inactive_item', 'type' => 'one_time', 'price' => 100, 'is_active' => false, ]); $response = $this->actingAs($user)->getJson(route('shop.items')); $response->assertStatus(200); $responseItems = collect($response->json('items')); $this->assertTrue($responseItems->contains('id', $activeItem->id)); $this->assertFalse($responseItems->contains('id', $inactiveItem->id)); } /** * 测试商店商品列表会包含新增的特效单次卡与周卡。 */ public function test_items_include_new_effect_shop_cards(): void { $user = User::factory()->create(); $response = $this->actingAs($user)->getJson(route('shop.items')); $response->assertOk(); $response->assertJsonFragment(['slug' => 'once_meteors']); $response->assertJsonFragment(['slug' => 'once_gold-rain']); $response->assertJsonFragment(['slug' => 'once_hearts']); $response->assertJsonFragment(['slug' => 'once_confetti']); $response->assertJsonFragment(['slug' => 'once_fireflies']); $response->assertJsonFragment(['slug' => 'once_sakura']); $response->assertJsonFragment(['slug' => 'week_sakura']); $response->assertJsonFragment(['slug' => 'week_meteors']); $response->assertJsonFragment(['slug' => 'week_gold-rain']); $response->assertJsonFragment(['slug' => 'week_hearts']); $response->assertJsonFragment(['slug' => 'week_confetti']); $response->assertJsonFragment(['slug' => 'week_fireflies']); } /** * 测试一次性道具可以正常购买。 */ public function test_can_buy_one_time_item() { $user = User::factory()->create(['jjb' => 500]); $item = ShopItem::firstOrCreate( ['slug' => 'rename_card_test'], [ 'name' => 'Rename Card Test', 'type' => 'one_time', 'price' => 100, 'is_active' => true, ]); $response = $this->actingAs($user)->postJson(route('shop.buy'), [ 'item_id' => $item->id, 'room_id' => 1, ]); $response->assertStatus(200); $response->assertJson(['status' => 'success']); $this->assertDatabaseHas('user_purchases', [ 'user_id' => $user->id, 'shop_item_id' => $item->id, ]); $this->assertDatabaseHas('users', [ 'id' => $user->id, 'jjb' => 400, ]); } /** * 测试余额不足时不能购买商品。 */ public function test_cannot_buy_if_insufficient_funds() { $user = User::factory()->create(['jjb' => 50]); $item = ShopItem::firstOrCreate( ['slug' => 'rename_card_test'], [ 'name' => 'Rename Card Test', 'type' => 'one_time', 'price' => 100, 'is_active' => true, ]); $response = $this->actingAs($user)->postJson(route('shop.buy'), [ 'item_id' => $item->id, ]); $response->assertStatus(400); $response->assertJson(['status' => 'error']); $this->assertDatabaseMissing('user_purchases', [ 'user_id' => $user->id, 'shop_item_id' => $item->id, ]); } /** * 测试已下架商品不能购买。 */ public function test_cannot_buy_inactive_item() { $user = User::factory()->create(['jjb' => 500]); $item = ShopItem::create([ 'name' => 'Old Card', 'slug' => 'old_card', 'type' => 'one_time', 'price' => 100, 'is_active' => false, ]); $response = $this->actingAs($user)->postJson(route('shop.buy'), [ 'item_id' => $item->id, ]); $response->assertStatus(400); $this->assertDatabaseMissing('user_purchases', [ 'user_id' => $user->id, ]); } /** * 测试改名卡可以被正常使用。 */ public function test_can_use_rename_card() { $user = User::factory()->create(['username' => 'OldName']); // Actually the service hardcodes 'rename_card' slug check: $item->slug === 'rename_card' // So we MUST use 'rename_card' $item = ShopItem::firstOrCreate( ['slug' => 'rename_card'], [ 'name' => 'Rename Card', 'type' => 'one_time', 'price' => 100, 'is_active' => true, ]); UserPurchase::create([ 'user_id' => $user->id, 'shop_item_id' => $item->id, 'status' => 'active', 'used_at' => null, 'cost_amount' => 100, 'currency_type' => 'gold', ]); $response = $this->actingAs($user)->postJson(route('shop.rename'), [ 'new_name' => 'NewName', ]); $response->assertStatus(200); $response->assertJson(['status' => 'success']); // Assert user's name is updated $this->assertDatabaseHas('users', [ 'id' => $user->id, 'username' => 'NewName', ]); // Assert card is used $this->assertDatabaseHas('user_purchases', [ 'user_id' => $user->id, 'shop_item_id' => $item->id, 'status' => 'used', ]); } }