0f6f38a70e
fix(supplier): реальные endpoint'ы отчёта «Запрос номеров» (discovery T3)
Discovery T3 на живом supplier-портале crm.bp-gr.ru (Playwright MCP)
вскрыл фактические endpoint'ы вместо placeholder'ов из spec §4.3:
- POST /admin/report/save-report (JSON body, selectType=49 + reportFilter)
— возвращает строку "OK", не JSON с id;
- GET /admin/report/load-reports — массив отчётов, id извлекается
title-match'ем «Запрос номеров с {from} по {to}»;
- GET /admin/report/getfile?id=N — 302 redirect на отдельный
download-host (oki.needcallbuy.ru), Laravel HTTP follows redirect.
SupplierPortalClient: requestNumbersReport/waitReportReady/downloadReport
переписаны под реальный контракт; request() +параметр asJson;
connectTimeout(30)+timeout(60) против flaky DNS resolve.
refresh-session.js: селекторы login-формы Yii2 — placeholder
input[name=login] → реальные #loginform-username/-password.
Тесты SupplierPortalClientReportTest + CsvReconcileJobTest адаптированы
под новый внутренний контракт. Pest 15/15, Larastan 0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@
78 lines
3.1 KiB
PHP
78 lines
3.1 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use App\Services\Supplier\SupplierPortalClient;
|
||
use Illuminate\Http\Client\Request;
|
||
use Illuminate\Support\Carbon;
|
||
use Illuminate\Support\Facades\Cache;
|
||
use Illuminate\Support\Facades\Http;
|
||
|
||
beforeEach(function (): void {
|
||
config(['services.supplier.portal_url' => 'https://crm.bp-gr.ru']);
|
||
Cache::store('redis')->put('supplier:session', ['phpsessid' => 'test', 'csrf' => 'test'], now()->addHour());
|
||
});
|
||
|
||
// Реальные endpoint'ы verified discovery T3 2026-05-19 через Playwright MCP:
|
||
// POST /admin/report/save-report (JSON body, response "OK" — text, не JSON)
|
||
// GET /admin/report/load-reports (array — каждая запись {id,title,status:"0"|"1",...})
|
||
// GET /admin/report/getfile?id=N (raw CSV body)
|
||
|
||
it('requestNumbersReport posts save-report and resolves id via load-reports by title match', function (): void {
|
||
Http::fake([
|
||
'crm.bp-gr.ru/admin/report/save-report' => Http::response('OK', 200),
|
||
'crm.bp-gr.ru/admin/report/load-reports' => Http::response([
|
||
['id' => '509196', 'title' => 'Запрос номеров с 2026-05-17 по 2026-05-18', 'status' => '0'],
|
||
['id' => '508346', 'title' => 'Запрос номеров с 2026-04-01 по 2026-04-30', 'status' => '1'],
|
||
], 200),
|
||
]);
|
||
|
||
$client = app(SupplierPortalClient::class);
|
||
$id = $client->requestNumbersReport(Carbon::parse('2026-05-17'), Carbon::parse('2026-05-18'));
|
||
|
||
expect($id)->toBe(509196);
|
||
|
||
Http::assertSent(function (Request $r): bool {
|
||
if (! str_ends_with($r->url(), '/admin/report/save-report')) {
|
||
return false;
|
||
}
|
||
if ($r->method() !== 'POST') {
|
||
return false;
|
||
}
|
||
$body = $r->data();
|
||
|
||
return ($body['reportForm']['selectType'] ?? null) === 49
|
||
&& ($body['reportFilter']['dateFrom'] ?? null) === '2026-05-17'
|
||
&& ($body['reportFilter']['dateTo'] ?? null) === '2026-05-18'
|
||
&& ($body['reportFilter']['types'] ?? null) === ['phones']
|
||
&& ($body['reportFilter']['prophones'] ?? null) === 'curr'
|
||
&& ($body['reportFilter']['gck_tech'] ?? null) === 'gck';
|
||
});
|
||
});
|
||
|
||
it('waitReportReady polls load-reports until our entry has status "1"', function (): void {
|
||
Http::fakeSequence('crm.bp-gr.ru/admin/report/load-reports')
|
||
->push([
|
||
['id' => '509196', 'title' => 'Запрос номеров с 2026-05-17 по 2026-05-18', 'status' => '0'],
|
||
], 200)
|
||
->push([
|
||
['id' => '509196', 'title' => 'Запрос номеров с 2026-05-17 по 2026-05-18', 'status' => '1'],
|
||
], 200);
|
||
|
||
$client = app(SupplierPortalClient::class);
|
||
$client->waitReportReady(509196);
|
||
|
||
expect(true)->toBeTrue();
|
||
});
|
||
|
||
it('downloadReport returns raw CSV body from getfile', function (): void {
|
||
Http::fake([
|
||
'crm.bp-gr.ru/admin/report/getfile*' => Http::response("Name;Tag;Phone\nB1_a.com;t;79991234567\n", 200),
|
||
]);
|
||
|
||
$client = app(SupplierPortalClient::class);
|
||
$csv = $client->downloadReport(509196);
|
||
|
||
expect($csv)->toContain('Name;Tag;Phone');
|
||
});
|