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); });