actingAs($this->makeUser(0))->get(route('admin.balances.index'))->assertForbidden(); } public function test_admin_can_view_transaction_log(): void { $this->mock(BalanceService::class, function (MockInterface $mock): void { $mock->shouldReceive('adminTransactions')->once()->with(null)->andReturn(new Collection()); }); $this->actingAs($this->makeUser(3)) ->get(route('admin.balances.index')) ->assertOk() ->assertSee('Слёзы Элуны') ->assertSee('Последние транзакции'); } public function test_admin_can_credit_account_balance(): void { $admin = $this->makeUser(3); $player = $this->makeUser(0, 7, 'PLAYER'); $this->mock(AzerothCoreAccountService::class, function (MockInterface $mock) use ($player): void { $mock->shouldReceive('findUserByUsername')->once()->with('PLAYER')->andReturn($player); }); $this->mock(BalanceService::class, function (MockInterface $mock) use ($admin): void { $transaction = new BalanceTransaction([ 'account_id' => 7, 'balance_after' => '150.00', ]); $mock->shouldReceive('adjustByAdmin') ->once() ->with(7, '50.00', 'credit', $admin->id, $admin->username, 'Компенсация') ->andReturn($transaction); }); $this->from(route('admin.balances.index')) ->actingAs($admin) ->post(route('admin.balances.adjust'), [ 'account' => 'PLAYER', 'direction' => 'credit', 'amount' => '50.00', 'reason' => 'Компенсация', ]) ->assertRedirect(route('admin.balances.index')) ->assertSessionHas('status', 'Счёт PLAYER изменён. Теперь на нём 150,00 Слёз Элуны.'); } private function makeUser(int $gmLevel, int $id = 1, string $username = 'ADMIN'): GameAccountUser { return new GameAccountUser( id: $id, username: $username, email: $username.'@EXAMPLE.COM', regMail: $username.'@EXAMPLE.COM', gmLevel: $gmLevel, locked: false, lastLoginAt: '2026-03-13 18:00:00', joinedAt: '2026-03-12 12:00:00', saltHex: str_repeat('AA', 32), verifierHex: str_repeat('BB', 32), ); } }