'superlevel'], ['body' => '100']); } /** * 测试银行信息接口返回本人余额和最近流水。 */ public function test_info_returns_balances_and_logs(): void { $user = User::factory()->create([ 'jjb' => 1000, 'bank_jjb' => 5000, ]); BankLog::create([ 'user_id' => $user->id, 'type' => 'deposit', 'amount' => 500, 'balance_after' => 5000, ]); $response = $this->actingAs($user)->getJson(route('bank.info')); $response->assertStatus(200); $response->assertJson([ 'status' => 'success', 'jjb' => 1000, 'bank_jjb' => 5000, ]); $response->assertJsonCount(1, 'logs'); } /** * 测试存款会把流通金币转入银行账户。 */ public function test_deposit_transfers_jjb_to_bank(): void { $user = User::factory()->create([ 'jjb' => 1000, 'bank_jjb' => 0, ]); $response = $this->actingAs($user)->postJson(route('bank.deposit'), [ 'amount' => 500, ]); $response->assertStatus(200); $response->assertJson([ 'status' => 'success', 'jjb' => 500, 'bank_jjb' => 500, ]); $this->assertDatabaseHas('users', [ 'id' => $user->id, 'jjb' => 500, 'bank_jjb' => 500, ]); $this->assertDatabaseHas('bank_logs', [ 'user_id' => $user->id, 'type' => 'deposit', 'amount' => 500, 'balance_after' => 500, ]); } /** * 测试流通金币不足时不能存款。 */ public function test_deposit_fails_if_insufficient_funds(): void { $user = User::factory()->create([ 'jjb' => 100, 'bank_jjb' => 0, ]); $response = $this->actingAs($user)->postJson(route('bank.deposit'), [ 'amount' => 500, ]); $response->assertStatus(200); $response->assertJson([ 'status' => 'error', ]); $this->assertDatabaseMissing('bank_logs', [ 'user_id' => $user->id, ]); } /** * 测试取款会把银行存款转回流通金币。 */ public function test_withdraw_transfers_bank_to_jjb(): void { $user = User::factory()->create([ 'jjb' => 0, 'bank_jjb' => 1000, ]); $response = $this->actingAs($user)->postJson(route('bank.withdraw'), [ 'amount' => 500, ]); $response->assertStatus(200); $response->assertJson([ 'status' => 'success', 'jjb' => 500, 'bank_jjb' => 500, ]); $this->assertDatabaseHas('bank_logs', [ 'user_id' => $user->id, 'type' => 'withdraw', 'amount' => 500, 'balance_after' => 500, ]); } /** * 测试银行余额不足时不能取款。 */ public function test_withdraw_fails_if_insufficient_funds(): void { $user = User::factory()->create([ 'jjb' => 0, 'bank_jjb' => 100, ]); $response = $this->actingAs($user)->postJson(route('bank.withdraw'), [ 'amount' => 500, ]); $response->assertStatus(200); $response->assertJson([ 'status' => 'error', ]); } /** * 测试普通用户查看存款排行时,别人存款被星号遮罩且本人存款可见。 */ public function test_ranking_masks_other_users_bank_balance_for_normal_user(): void { $user = User::factory()->create([ 'bank_jjb' => 750, 'username' => 'Viewer', 'user_level' => 10, ]); User::factory()->create(['bank_jjb' => 1000, 'username' => 'Rich']); $response = $this->actingAs($user)->getJson(route('bank.ranking')); $response->assertStatus(200); $response->assertJson([ 'status' => 'success', ]); $ranking = $response->json('ranking'); $this->assertCount(2, $ranking); $this->assertEquals('Rich', $ranking[0]['username']); $this->assertSame('******', $ranking[0]['bank_jjb']); $this->assertTrue($ranking[0]['can_reveal']); $this->assertEquals('Viewer', $ranking[1]['username']); $this->assertSame(750, $ranking[1]['bank_jjb']); $this->assertFalse($ranking[1]['can_reveal']); } /** * 测试 superlevel 用户查看存款排行时所有金额真实可见。 */ public function test_ranking_shows_all_bank_balances_for_superlevel_user(): void { $admin = User::factory()->create([ 'user_level' => 100, 'bank_jjb' => 1, ]); User::factory()->create(['bank_jjb' => 1000, 'username' => 'Rich']); $response = $this->actingAs($admin)->getJson(route('bank.ranking')); $response->assertOk(); $ranking = $response->json('ranking'); $this->assertSame(1000, $ranking[0]['bank_jjb']); $this->assertFalse($ranking[0]['can_reveal']); } /** * 测试普通用户付费查看别人存款时扣除金币并写入流水。 */ public function test_reveal_balance_charges_normal_user_and_returns_target_bank_balance(): void { $viewer = User::factory()->create([ 'jjb' => 1500, 'user_level' => 10, ]); $target = User::factory()->create([ 'username' => 'TargetUser', 'bank_jjb' => 4321, ]); $response = $this->actingAs($viewer)->postJson(route('user.reveal-info'), [ 'user_id' => $target->id, 'asset' => 'bank_jjb', ]); $response->assertOk() ->assertJsonPath('status', 'success') ->assertJsonPath('asset', 'bank_jjb') ->assertJsonPath('value', 4321) ->assertJsonPath('charged', true) ->assertJsonPath('jjb', 500); $this->assertDatabaseHas('users', [ 'id' => $viewer->id, 'jjb' => 500, ]); $this->assertDatabaseHas('user_currency_logs', [ 'user_id' => $viewer->id, 'currency' => 'gold', 'amount' => -1000, 'balance_after' => 500, 'source' => CurrencySource::USER_INFO_REVEAL->value, 'remark' => '查看 TargetUser 的存款', ]); } /** * 测试金币不足时不能付费查看别人存款,也不会泄露金额。 */ public function test_reveal_balance_fails_without_enough_gold(): void { $viewer = User::factory()->create([ 'jjb' => 999, 'user_level' => 10, ]); $target = User::factory()->create([ 'bank_jjb' => 4321, ]); $response = $this->actingAs($viewer)->postJson(route('user.reveal-info'), [ 'user_id' => $target->id, 'asset' => 'bank_jjb', ]); $response->assertOk() ->assertJsonPath('status', 'error') ->assertJsonMissingPath('value'); $this->assertDatabaseHas('users', [ 'id' => $viewer->id, 'jjb' => 999, ]); $this->assertSame(0, UserCurrencyLog::query() ->where('user_id', $viewer->id) ->where('source', CurrencySource::USER_INFO_REVEAL->value) ->count()); } /** * 测试查看自己存款不扣费。 */ public function test_reveal_own_balance_is_free(): void { $viewer = User::factory()->create([ 'jjb' => 10, 'bank_jjb' => 2222, ]); $response = $this->actingAs($viewer)->postJson(route('user.reveal-info'), [ 'user_id' => $viewer->id, 'asset' => 'bank_jjb', ]); $response->assertOk() ->assertJsonPath('status', 'success') ->assertJsonPath('asset', 'bank_jjb') ->assertJsonPath('value', 2222) ->assertJsonPath('charged', false) ->assertJsonPath('jjb', 10); $this->assertSame(0, UserCurrencyLog::query() ->where('user_id', $viewer->id) ->where('source', CurrencySource::USER_INFO_REVEAL->value) ->count()); } /** * 测试 superlevel 用户查看别人存款不扣费。 */ public function test_superlevel_reveal_other_balance_is_free(): void { $admin = User::factory()->create([ 'jjb' => 10, 'user_level' => 100, ]); $target = User::factory()->create([ 'bank_jjb' => 3333, ]); $response = $this->actingAs($admin)->postJson(route('user.reveal-info'), [ 'user_id' => $target->id, 'asset' => 'bank_jjb', ]); $response->assertOk() ->assertJsonPath('status', 'success') ->assertJsonPath('asset', 'bank_jjb') ->assertJsonPath('value', 3333) ->assertJsonPath('charged', false) ->assertJsonPath('jjb', 10); } }