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

52 lines
2.2 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Models\SalesUser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Hash;
/**
* Регрессия боевого инцидента 24.07.2026.
*
* Портал отдела продаж (guard 'sales', Sanctum Bearer) на stateful-домене
* lk.liderra.ru «перебивался» сессией обычного кабинета (guard 'web'):
* Laravel\Sanctum\Guard сначала смотрит config('sanctum.guard')=['web'] и,
* если в браузере открыт обычный кабинет (активная web-сессия), возвращает
* App\Models\User ВМЕСТО SalesUser — даже не заглянув в Bearer-токен. Итог —
* TypeError/`User::isHead()` → 500 на всех защищённых маршрутах портала.
*
* Инвариант: маршруты /api/sales/* авторизуются ТОЛЬКО по своему токену и не
* зависят от того, залогинен ли в том же браузере обычный кабинет.
*/
uses(DatabaseTransactions::class);
function gtp_makeHead(): SalesUser
{
return SalesUser::create([
'name' => 'Head '.uniqid(),
'email' => 'gtp-head-'.uniqid().'@test.local',
'password' => Hash::make('secret'),
'role' => 'head',
'is_active' => true,
]);
}
it('авторизует портал по токену, игнорируя открытую web-сессию обычного кабинета', function () {
$head = gtp_makeHead();
// В том же браузере параллельно открыт обычный кабинет — активная web-сессия.
$webUser = User::factory()->create();
$this->actingAs($webUser, 'web');
$token = $head->createToken('sales')->plainTextToken;
$resp = $this
->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/sales/overview?period=d30');
// Портал должен ответить начальнику (200), а не 500 из-за подмены на User.
$resp->assertOk();
});