Files
portal/app/tests/Feature/TrackEndpointTest.php
T

75 lines
3.6 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;
uses(DatabaseTransactions::class);
uses(SharesSupplierPdo::class);
test('первое событие view создаёт гостя и ставит куку', function () {
$r = $this->postJson('/api/track', [
'event' => 'view',
'host' => 'liderra.ru',
'path' => '/',
'referrer' => 'https://krasnoyarsk.hh.ru/vacancy/1',
], ['User-Agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X)']);
$r->assertStatus(204);
$r->assertCookie('lid_vid');
$v = DB::table('site_visitors')->first();
expect($v->channel)->toBe('hh');
expect($v->device)->toBe('phone');
expect($v->is_human)->toBeFalse(); // пока только браузер, не человек
expect(DB::table('site_events')->where('event', 'view')->count())->toBe(1);
});
test('utm-метка из ссылки определяет канал', function () {
$this->postJson('/api/track', [
'event' => 'view', 'host' => 'liderra.ru', 'path' => '/',
'utm' => ['utm_source' => 'sms', 'utm_campaign' => 'rassylka-13-07'],
])->assertStatus(204);
$v = DB::table('site_visitors')->first();
expect($v->channel)->toBe('sms');
expect($v->utm_campaign)->toBe('rassylka-13-07');
});
test('повторный view с той же кукой не создаёт второго гостя', function () {
$first = $this->postJson('/api/track', ['event' => 'view', 'host' => 'liderra.ru', 'path' => '/']);
// getCookie() без второго аргумента — decrypt=true (по умолчанию), возвращает
// ПЛОСКОЕ значение (снят слой encrypt+CookieValuePrefix). withCookie() ниже сам
// шифрует заново — если взять уже-зашифрованное значение (decrypt=false), получится
// двойное шифрование и сервер cookie не распознает (заведёт нового гостя).
$vid = $first->getCookie('lid_vid')->getValue();
// withCredentials(): postJson/getJson по умолчанию НЕ прикладывают cookie
// (как XHR с credentials:'omit') — withCookie() без него молча теряется.
// В браузере маячок шлёт fetch с credentials:'include', поэтому куку видит всегда.
$this->withCredentials()->withCookie('lid_vid', $vid)
->postJson('/api/track', ['event' => 'view', 'host' => 'lk.liderra.ru', 'path' => '/login'])
->assertStatus(204);
expect(DB::table('site_visitors')->count())->toBe(1);
expect(DB::table('site_events')->count())->toBe(2);
});
test('событие alive помечает гостя как живого человека', function () {
$first = $this->postJson('/api/track', ['event' => 'view', 'host' => 'liderra.ru', 'path' => '/']);
$vid = $first->getCookie('lid_vid')->getValue();
$this->withCredentials()->withCookie('lid_vid', $vid)
->postJson('/api/track', ['event' => 'alive', 'host' => 'liderra.ru', 'path' => '/'])
->assertStatus(204);
expect((bool) DB::table('site_visitors')->first()->is_human)->toBeTrue();
});
test('неизвестное событие отклоняется', function () {
$this->postJson('/api/track', ['event' => 'drop_table', 'host' => 'liderra.ru'])
->assertStatus(422);
expect(DB::table('site_events')->count())->toBe(0);
});