189 lines
6.6 KiB
PHP
189 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\GameAccountUser;
|
|
use App\Services\AzerothCoreAccountService;
|
|
use App\Services\InviteCodeService;
|
|
use Illuminate\Support\Collection;
|
|
use Mockery\MockInterface;
|
|
use Tests\TestCase;
|
|
|
|
class AdminAccountsFeatureTest extends TestCase
|
|
{
|
|
public function test_guest_is_redirected_to_login_for_admin(): void
|
|
{
|
|
$response = $this->get(route('admin.accounts.index'));
|
|
|
|
$response->assertRedirect(route('login'));
|
|
}
|
|
|
|
public function test_regular_player_cannot_open_admin_accounts_page(): void
|
|
{
|
|
$response = $this->actingAs($this->makeUser(0))->get(route('admin.accounts.index'));
|
|
|
|
$response->assertForbidden();
|
|
}
|
|
|
|
public function test_admin_can_open_accounts_page(): void
|
|
{
|
|
$this->mock(AzerothCoreAccountService::class, function (MockInterface $mock): void {
|
|
$mock->shouldReceive('accountTypeStats')
|
|
->once()
|
|
->with(null)
|
|
->andReturn(['players' => 1, 'bots' => 1]);
|
|
|
|
$mock->shouldReceive('listAccounts')
|
|
->once()
|
|
->with(null, 'players')
|
|
->andReturn(new Collection([
|
|
[
|
|
'id' => 1,
|
|
'username' => 'ADMIN',
|
|
'email' => 'ADMIN@EXAMPLE.COM',
|
|
'reg_mail' => 'ADMIN@EXAMPLE.COM',
|
|
'gm_level' => 3,
|
|
'access_label' => 'Администратор',
|
|
'locked' => false,
|
|
'online' => false,
|
|
'joined_at' => '12.03.2026 12:00',
|
|
'last_login_at' => '13.03.2026 18:00',
|
|
'characters' => new Collection([
|
|
[
|
|
'name' => 'Stormmage',
|
|
'race' => 'Человек',
|
|
'class' => 'Маг',
|
|
'level' => 80,
|
|
'online' => false,
|
|
],
|
|
]),
|
|
],
|
|
]));
|
|
});
|
|
|
|
$this->mock(InviteCodeService::class, function (MockInterface $mock): void {
|
|
$mock->shouldReceive('latest')
|
|
->once()
|
|
->andReturn(new Collection());
|
|
|
|
$mock->shouldReceive('stats')
|
|
->once()
|
|
->andReturn(['total' => 0, 'available' => 0, 'redeemed' => 0]);
|
|
});
|
|
|
|
$response = $this->actingAs($this->makeUser(3))->get(route('admin.accounts.index'));
|
|
|
|
$response->assertOk();
|
|
$response->assertSee('Stormmage');
|
|
$response->assertSee('Аккаунты и персонажи');
|
|
$response->assertSee('Управление инвайт-кодами');
|
|
$response->assertSee('Игроки · 1');
|
|
$response->assertSee('Боты · 1');
|
|
}
|
|
|
|
public function test_admin_can_open_bots_tab(): void
|
|
{
|
|
$this->mock(AzerothCoreAccountService::class, function (MockInterface $mock): void {
|
|
$mock->shouldReceive('accountTypeStats')
|
|
->once()
|
|
->with(null)
|
|
->andReturn(['players' => 4, 'bots' => 2]);
|
|
|
|
$mock->shouldReceive('listAccounts')
|
|
->once()
|
|
->with(null, 'bots')
|
|
->andReturn(new Collection([
|
|
[
|
|
'id' => 7,
|
|
'username' => 'RNDBOT0007',
|
|
'email' => '',
|
|
'reg_mail' => '',
|
|
'gm_level' => 0,
|
|
'access_label' => 'Игрок',
|
|
'locked' => false,
|
|
'online' => false,
|
|
'joined_at' => '14.03.2026 01:00',
|
|
'last_login_at' => '14.03.2026 01:30',
|
|
'characters' => new Collection(),
|
|
],
|
|
]));
|
|
});
|
|
|
|
$this->mock(InviteCodeService::class, function (MockInterface $mock): void {
|
|
$mock->shouldReceive('latest')
|
|
->once()
|
|
->andReturn(new Collection());
|
|
|
|
$mock->shouldReceive('stats')
|
|
->once()
|
|
->andReturn(['total' => 0, 'available' => 0, 'redeemed' => 0]);
|
|
});
|
|
|
|
$response = $this->actingAs($this->makeUser(3))->get(route('admin.accounts.index', ['tab' => 'bots']));
|
|
|
|
$response->assertOk();
|
|
$response->assertSee('RNDBOT0007');
|
|
$response->assertSee('Боты · 2');
|
|
}
|
|
|
|
public function test_admin_can_update_access_level(): void
|
|
{
|
|
$this->mock(AzerothCoreAccountService::class, function (MockInterface $mock): void {
|
|
$mock->shouldReceive('findUserById')
|
|
->once()
|
|
->with(12)
|
|
->andReturn($this->makeUser(0));
|
|
|
|
$mock->shouldReceive('updateAccessLevel')
|
|
->once()
|
|
->with(12, 2);
|
|
});
|
|
|
|
$response = $this->from(route('admin.accounts.index'))
|
|
->actingAs($this->makeUser(3))
|
|
->patch(route('admin.accounts.access.update', 12), [
|
|
'gmlevel' => 2,
|
|
]);
|
|
|
|
$response->assertRedirect(route('admin.accounts.index'));
|
|
$response->assertSessionHas('status', 'Уровень доступа обновлён.');
|
|
}
|
|
|
|
public function test_admin_can_create_invite_codes(): void
|
|
{
|
|
$admin = $this->makeUser(3);
|
|
|
|
$this->mock(InviteCodeService::class, function (MockInterface $mock) use ($admin): void {
|
|
$mock->shouldReceive('createCodes')
|
|
->once()
|
|
->with(3, $admin)
|
|
->andReturn(new Collection([1, 2, 3]));
|
|
});
|
|
|
|
$response = $this->from(route('admin.accounts.index'))
|
|
->actingAs($admin)
|
|
->post(route('admin.invite-codes.store'), [
|
|
'quantity' => 3,
|
|
]);
|
|
|
|
$response->assertRedirect(route('admin.accounts.index'));
|
|
$response->assertSessionHas('status', 'Создано инвайт-кодов: 3.');
|
|
}
|
|
|
|
private function makeUser(int $gmLevel): GameAccountUser
|
|
{
|
|
return new GameAccountUser(
|
|
id: 1,
|
|
username: 'ADMIN',
|
|
email: 'ADMIN@EXAMPLE.COM',
|
|
regMail: 'ADMIN@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),
|
|
);
|
|
}
|
|
}
|