Files
portal/app/tests/Feature/Auth/AuthControllerTest.php
T
Дмитрий fdff36c553 refactor(auth): убрать одношаговый register (заменён start/verify)
Удалён старый POST /api/auth/register (метод + роут + RegisterRequest + 3 теста);
регистрация теперь только через register/start → register/verify. SPA-роут
страницы /register сохранён. Larastan baseline перегенерирован (counts
AuthControllerTest 9→8 / 14→10 после удаления тестов).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:13:11 +03:00

163 lines
5.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Hash;
uses(DatabaseTransactions::class);
beforeEach(function () {
$this->tenant = Tenant::factory()->create();
});
test('POST /api/auth/login возвращает user + requires_2fa=false для обычного user', function () {
$user = User::factory()->create([
'tenant_id' => $this->tenant->id,
'email' => 'login-test@example.ru',
'password_hash' => Hash::make('secret-pass-123'),
'totp_enabled' => false,
'is_active' => true,
]);
$response = $this->postJson('/api/auth/login', [
'email' => 'login-test@example.ru',
'password' => 'secret-pass-123',
]);
$response->assertOk();
$response->assertJsonPath('user.id', $user->id);
$response->assertJsonPath('user.email', 'login-test@example.ru');
$response->assertJsonPath('requires_2fa', false);
expect($response->json('user'))->not->toHaveKey('password_hash');
});
test('POST /api/auth/login c totp_enabled=true возвращает requires_2fa=true', function () {
User::factory()->create([
'tenant_id' => $this->tenant->id,
'email' => 'totp-user@example.ru',
'password_hash' => Hash::make('secret-pass-123'),
'totp_enabled' => true,
]);
$response = $this->postJson('/api/auth/login', [
'email' => 'totp-user@example.ru',
'password' => 'secret-pass-123',
]);
$response->assertOk();
$response->assertJsonPath('requires_2fa', true);
});
test('POST /api/auth/login возвращает 422 при неверном пароле', function () {
User::factory()->create([
'tenant_id' => $this->tenant->id,
'email' => 'wrong-pass@example.ru',
'password_hash' => Hash::make('right-pass-123'),
]);
$response = $this->postJson('/api/auth/login', [
'email' => 'wrong-pass@example.ru',
'password' => 'wrong-pass-456',
]);
$response->assertStatus(422);
$response->assertJsonPath('errors.email.0', 'Неверный email или пароль.');
});
test('POST /api/auth/login возвращает 422 для несуществующего email', function () {
$response = $this->postJson('/api/auth/login', [
'email' => 'nonexistent@example.ru',
'password' => 'any-password',
]);
$response->assertStatus(422);
});
test('POST /api/auth/login возвращает 422 для заблокированного аккаунта (is_active=false)', function () {
User::factory()->create([
'tenant_id' => $this->tenant->id,
'email' => 'blocked@example.ru',
'password_hash' => Hash::make('right-pass-123'),
'is_active' => false,
]);
$response = $this->postJson('/api/auth/login', [
'email' => 'blocked@example.ru',
'password' => 'right-pass-123',
]);
$response->assertStatus(422);
$response->assertJsonPath('errors.email.0', 'Аккаунт заблокирован.');
});
test('POST /api/auth/login валидирует email format и password min:8', function () {
$response = $this->postJson('/api/auth/login', [
'email' => 'not-an-email',
'password' => 'short',
]);
$response->assertStatus(422);
$response->assertJsonValidationErrors(['email', 'password']);
});
test('POST /api/auth/login обновляет last_login_at у user', function () {
$user = User::factory()->create([
'tenant_id' => $this->tenant->id,
'email' => 'lastlogin@example.ru',
'password_hash' => Hash::make('secret-pass-123'),
'last_login_at' => null,
]);
$this->postJson('/api/auth/login', [
'email' => 'lastlogin@example.ru',
'password' => 'secret-pass-123',
])->assertOk();
expect($user->fresh()->last_login_at)->not->toBeNull();
});
test('GET /api/auth/me возвращает 401 без авторизации', function () {
$this->getJson('/api/auth/me')->assertStatus(401);
});
test('GET /api/auth/me возвращает user после login', function () {
$user = User::factory()->create([
'tenant_id' => $this->tenant->id,
'email' => 'me-test@example.ru',
'password_hash' => Hash::make('secret-pass-123'),
]);
$this->postJson('/api/auth/login', [
'email' => 'me-test@example.ru',
'password' => 'secret-pass-123',
])->assertOk();
$this->getJson('/api/auth/me')
->assertOk()
->assertJsonPath('user.id', $user->id)
->assertJsonPath('user.email', 'me-test@example.ru');
});
test('POST /api/auth/logout успешно завершает сессию (200 + flash-message)', function () {
User::factory()->create([
'tenant_id' => $this->tenant->id,
'email' => 'logout-test@example.ru',
'password_hash' => Hash::make('secret-pass-123'),
]);
$this->postJson('/api/auth/login', [
'email' => 'logout-test@example.ru',
'password' => 'secret-pass-123',
])->assertOk();
// logout возвращает 200 с message. Полное invalidate-session тестирование
// проблемно в Pest-runtime (cookie-jar держит session между запросами теста);
// это тестируется через Pest browser-mode — отдельный коммит.
$this->postJson('/api/auth/logout')
->assertOk()
->assertJsonPath('message', 'Вы вышли из системы.');
});