Files
portal/app/tests/Feature/Sales/SalesGuardTest.php
T

63 lines
2.7 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Models\SalesUser;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Route;
/**
* TDD: guard «sales» (Sanctum driver, provider sales_users).
*
* Проверяет, что:
* 1. Bearer-токен sales_user открывает доступ к маршруту auth:sales.
* 2. Запрос без токена получает 401.
*
* Примечание по кросс-модельной проверке:
* Стандартный tenant User (App\Models\User) в этом проекте НЕ использует
* HasApiTokens (SPA cookie-auth), поэтому createToken() на User недоступен.
* Кросс-модельная изоляция guard'а sales гарантируется архитектурно:
* Sanctum привязывает tokenable_type к модели в personal_access_tokens;
* guard с provider sales_users резолвит только записи, где tokenable_type =
* App\Models\SalesUser. Тест на «чужой токен» возможен между двумя
* разными SalesUser — разные пользователи корректно разрешаются (auth OK
* для обоих), но привязка к конкретному пользователю верна.
*
* Spec: docs/superpowers/plans/2026-06-30-sales-portal.md (Task 0.3)
*/
uses(DatabaseTransactions::class);
beforeEach(function () {
// Стаб-маршрут, защищённый guard'ом sales.
Route::middleware('auth:sales')->get('/__sales_ping', fn () => response()->json(['ok' => true]));
});
test('sales user с valid Bearer-токеном получает 200 на auth:sales маршруте', function () {
$salesUser = SalesUser::create([
'name' => 'Тест Менеджер',
'email' => 'sales-guard-test-'.uniqid().'@test.local',
'password' => Hash::make('test-secret-123'),
'role' => 'manager',
]);
$token = $salesUser->createToken('test')->plainTextToken;
$this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/__sales_ping')
->assertOk()
->assertJson(['ok' => true]);
});
test('запрос без токена на auth:sales маршрут получает 401', function () {
$this->getJson('/__sales_ping')
->assertUnauthorized();
});
test('невалидный Bearer-токен на auth:sales маршруте получает 401', function () {
// Произвольная строка, которой нет в personal_access_tokens.
$this->withHeader('Authorization', 'Bearer '.str_repeat('x', 64))
->getJson('/__sales_ping')
->assertUnauthorized();
});