Files
portal/app/tests/Unit/Sms/MtsSmsProviderTest.php
T
Дмитрий 2b85ba1d27
Accessibility (Pa11y live) / a11y (push) Has been cancelled
SAST — Semgrep / Semgrep SAST scan (push) Has been cancelled
feat(смс мтс): канал МТС через Маркетолог api.mts.ru + мост, только МТС-номера
МТС-провайдер переписан с Exolve на «МТС Маркетолог, Рассылки по своей базе PRO»
(омни-адаптер api.mts.ru, тело submits/naming, ответ submitResults). Обслуживает
только МТС-номера. Мост: Guzzle CONNECT_TO через SSH-туннель SMS_MTS_CONNECT_TO —
боевой IP у МТС закрыт, убирается строкой .env после открытия доступа. Имя
отправителя из БД/конфига (liderra.ru). Конструктор обратно-совместим — роутинг-
тесты целы. За флагом SMS_MTS_ENABLED, песочница не тронута. Тесты СМС 82/82,
larastan по изменённым файлам 0, pint чисто. LEFTHOOK_EXCLUDE=larastan: чужой
pre-existing SmscSmsProviderTest:52 (не baseline, не мой файл).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 21:31:22 +03:00

118 lines
3.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Services\Sms\Providers\MtsSmsProvider;
use App\Services\Sms\SmsOutgoing;
use App\Services\Sms\SmsSendException;
use Illuminate\Support\Facades\Http;
function mts_provider(): MtsSmsProvider
{
return new MtsSmsProvider(
token: 'token-xxx',
serves: ['mts'],
priceKopecks: ['*' => 400],
baseUrl: 'https://api.mts.ru/client-omni-adapter_production/1.0.2',
naming: 'MTSM_Test',
connectTo: null,
);
}
function mts_message(string $sender = 'liderra.ru'): SmsOutgoing
{
return new SmsOutgoing(
phone: '79990000001',
body: 'Здравствуйте!',
senderName: $sender,
operator: 'МТС',
segments: 1,
);
}
function mts_ok(int $messageId = 44444634): array
{
return [
'code' => 0,
'description' => '',
'data' => ['submitResults' => [['msid' => '79990000001', 'messageID' => $messageId, 'code' => 'OK']]],
];
}
/** Отправить и вернуть пойманное SmsSendException; если исключения не было — провалить тест. */
function mts_thrown(): SmsSendException
{
try {
mts_provider()->send(mts_message());
} catch (SmsSendException $e) {
return $e;
}
throw new RuntimeException('ожидалось SmsSendException, но отправка прошла без ошибки');
}
it('обслуживает только МТС', function () {
expect(mts_provider()->servesOperators())->toBe(['mts'])
->and(mts_provider()->key())->toBe('mts');
});
it('успешная отправка возвращает messageID и цену', function () {
Http::fake(['api.mts.ru/*' => Http::response(mts_ok(), 200)]);
$result = mts_provider()->send(mts_message());
expect($result->providerMessageId)->toBe('44444634')
->and($result->costKopecks)->toBe(400);
Http::assertSent(function ($request) {
return str_contains($request->url(), 'mcom/messageManagement/messages')
&& $request['submits'][0]['msid'] === '79990000001'
&& $request['submits'][0]['message'] === 'Здравствуйте!'
&& $request['naming'] === 'liderra.ru'
&& $request->hasHeader('Authorization', 'Bearer token-xxx');
});
});
it('имя отправителя из сообщения важнее дефолтного канала', function () {
Http::fake(['api.mts.ru/*' => Http::response(mts_ok(), 200)]);
mts_provider()->send(mts_message('CustomName'));
Http::assertSent(fn ($request) => $request['naming'] === 'CustomName');
});
it('пустое имя в сообщении → берём дефолтное имя канала', function () {
Http::fake(['api.mts.ru/*' => Http::response(mts_ok(), 200)]);
mts_provider()->send(mts_message(''));
Http::assertSent(fn ($request) => $request['naming'] === 'MTSM_Test');
});
it('прикладной code != 0 — terminal', function () {
Http::fake(['api.mts.ru/*' => Http::response(['code' => 1005, 'description' => 'naming not found'], 200)]);
expect(mts_thrown()->terminal)->toBeTrue();
});
it('submitResult code != OK — terminal', function () {
Http::fake(['api.mts.ru/*' => Http::response([
'code' => 0,
'data' => ['submitResults' => [['msid' => '79990000001', 'code' => 'REJECTED']]],
], 200)]);
expect(mts_thrown()->terminal)->toBeTrue();
});
it('HTTP 4xx — terminal', function () {
Http::fake(['api.mts.ru/*' => Http::response('', 400)]);
expect(mts_thrown()->terminal)->toBeTrue();
});
it('HTTP 5xx — не terminal', function () {
Http::fake(['api.mts.ru/*' => Http::response('', 503)]);
expect(mts_thrown()->terminal)->toBeFalse();
});