42 lines
2.4 KiB
PHP
42 lines
2.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
use App\Services\Autopodbor\Agent\Fetch\CurlPlaywrightFetcher;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Регрессия боевого бага (07.07.2026, конкурент «Центрофинанс», tenant info@lkomega.ru):
|
||
|
|
* curl успешно скачивал сайт с tel:-номерами, но рендер (node render-page.cjs) висел на
|
||
|
|
* networkidle и падал по таймауту. Symfony Process::run() при таймауте БРОСАЕТ
|
||
|
|
* ProcessTimedOutException — и оно вылетало из site(), обнуляя уже успешный curl.
|
||
|
|
* Итог: ни одного номера с сайта. Рендер обязан быть НЕ фатальным: его падение не должно
|
||
|
|
* ни ронять site()/directory(), ни терять номера, добытые curl.
|
||
|
|
*
|
||
|
|
* Сиды конструктора (curlRunner/nodeRunner) подменяют сеть и запуск node — без подпроцесса.
|
||
|
|
* nodeRunner бросает исключение = «рендер завис/упал» (в бою это ProcessTimedOutException;
|
||
|
|
* продакшн ловит \Throwable, тип не важен).
|
||
|
|
*/
|
||
|
|
function fetcherWithFailingRender(?callable $curl = null): CurlPlaywrightFetcher
|
||
|
|
{
|
||
|
|
return new CurlPlaywrightFetcher(
|
||
|
|
timeout: 1,
|
||
|
|
curlRunner: $curl ?? fn (string $url): string => '',
|
||
|
|
nodeRunner: function (string $script, string $url): ?array {
|
||
|
|
throw new \RuntimeException('render timed out');
|
||
|
|
},
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
it('site(): при падении рендера НЕ теряет номера, добытые curl', function () {
|
||
|
|
$curl = fn (string $url): string => '<a href="tel:88007003767">8 800</a><a href="tel:84950110359">8 495</a>';
|
||
|
|
|
||
|
|
// 8.8.8.8 — публичный IP: проходит isSafeUrl без DNS; сеть не трогаем (curl подменён).
|
||
|
|
$site = fetcherWithFailingRender($curl)->site('https://8.8.8.8/');
|
||
|
|
|
||
|
|
expect($site->rawHtml)->toContain('tel:88007003767')
|
||
|
|
->and($site->rawHtml)->toContain('tel:84950110359')
|
||
|
|
->and($site->visiblePhones)->toBe([]); // рендер упал — видимых нет, но curl цел
|
||
|
|
});
|
||
|
|
|
||
|
|
it('directory(): при падении рендера возвращает [] вместо исключения', function () {
|
||
|
|
expect(fetcherWithFailingRender()->directory('https://8.8.8.8/'))->toBe([]);
|
||
|
|
});
|