Files
portal/app/tests/Feature/Http/Webhook/SupplierWebhookValidationFormatTest.php
T

66 lines
2.5 KiB
PHP
Raw Normal View History

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