Files
portal/app/tests/Feature/Http/Webhook/SupplierWebhookValidationFormatTest.php
T
Дмитрий b92d9b3bfc test(supplier-webhook): assert JSON 422 for non-JSON Accept clients (failing)
Reproduces 302-redirect bug observed on prod 2026-05-25 — when supplier
crm.bp-gr.ru POSTs without Accept: application/json, Laravel renders
ValidationException as redirect to /, losing body. Test calls webhook
without Accept header and asserts JSON 422 response. Will fail until
bootstrap/app.php has render(ValidationException) for api/webhook/supplier/*.
2026-05-25 17:37:44 +03:00

66 lines
2.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
use App\Models\SystemSetting;
use Illuminate\Foundation\Testing\DatabaseTransactions;
uses(DatabaseTransactions::class);
beforeEach(function () {
SystemSetting::query()
->where('key', 'supplier_webhook_secret')
->update(['value' => 'test-secret-32chars-aaaaaaaaaaaaaa']);
SystemSetting::query()
->where('key', 'supplier_ip_allowlist')
->update(['value' => '[]']);
});
it('returns 422 JSON when supplier posts invalid payload WITHOUT Accept: application/json header', function () {
// Воспроизводит реальное поведение crm.bp-gr.ru: POST без Accept-JSON.
// До фикса (302→422) Laravel редиректил на / с Set-Cookie, поставщик
// терял тело запроса. После фикса всегда JSON.
$response = $this->call(
'POST',
'/api/webhook/supplier/test-secret-32chars-aaaaaaaaaaaaaa',
[], // params
[], // cookies
[], // files
['HTTP_CONTENT_TYPE' => 'application/x-www-form-urlencoded'], // server: НЕТ Accept JSON
http_build_query([
'vid' => 1,
'project' => 'invalid_no_b_prefix',
'phone' => '79991234567',
'time' => time(),
])
);
$response->assertStatus(422);
expect($response->headers->get('Content-Type'))->toContain('application/json');
$response->assertJsonStructure(['message', 'errors' => ['project']]);
});
it('still works correctly for postJson clients (regression)', function () {
$response = $this->postJson('/api/webhook/supplier/test-secret-32chars-aaaaaaaaaaaaaa', [
'vid' => 1,
'project' => 'invalid_no_b_prefix',
'phone' => '79991234567',
'time' => time(),
]);
$response->assertStatus(422)->assertJsonValidationErrors('project');
});
it('non-webhook routes still use default render (no JSON forced)', function () {
// Регрессионный тест: дефолтный render остальных routes не сломан
// (например /login — должен возвращать redirect, а не JSON).
$response = $this->call(
'POST',
'/login',
['email' => 'bad', 'password' => ''],
[], [], [],
);
// Любой не-200 кроме 422-JSON допустим — главное чтобы наш fix не перехватил
expect($response->headers->get('Content-Type'))->not->toContain('application/json');
});