Files
portal/app/tests/Feature/ClientSms/DeliveryReporterMtsTest.php
T

128 lines
5.3 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Services\Sms\Providers\MtsSmsProvider;
use App\Services\Sms\SmsDeliveryState;
use App\Services\Sms\SmsSendException;
use Illuminate\Support\Facades\Http;
/**
* Строка листа 5.1: по каждому номеру видна настоящая судьба.
*
* 🔴 Форма ответа взята из ЖИВОЙ пробы 30.07 (журнал В-211), а НЕ из документации
* МТС: там описан вход по логину-паролю (`events_info` с `message_id`/`event_at`),
* а мы ходим по токену и получаем `data[].statuses[]`. Тест на выдуманной форме
* охранял бы выдумку (урок В-72: записанный чужой вывод — гипотеза, не факт).
*
* Помощники с префиксом mtsDelivery* — имена функций в Pest ГЛОБАЛЬНЫЕ.
* Телефоны только синтетические 7999… — реальные НИКОГДА.
*/
function mtsDeliveryProvider(): MtsSmsProvider
{
return new MtsSmsProvider('токен', ['mts'], ['*' => 300], 'https://api.mts.test/v1');
}
/**
* Ответ МТС на вопрос о судьбе — ровно той формы, что пришла живьём.
*
* @param array<int, array<string, mixed>> $statuses
* @return array<string, mixed>
*/
function mtsDeliveryBody(string $messageId, array $statuses): array
{
return ['code' => 0, 'data' => [['messageID' => $messageId, 'statuses' => $statuses]]];
}
it('читает доставленное сообщение по живой форме ответа', function () {
Http::fake(['*' => Http::response(mtsDeliveryBody('44747238', [[
'msid' => '79990000001',
'status' => 'Delivered',
'date' => '2026-07-30T16:31:02',
'userDeliveryDate' => '2026-07-30T16:31:40',
'partCount' => 2,
'isViber' => false,
'trafficPatternType' => 'service',
'cost' => 3.4,
]]))]);
$reports = mtsDeliveryProvider()->fetchDelivery(['44747238']);
expect($reports)->toHaveCount(1);
expect($reports[0]->providerMessageId)->toBe('44747238');
expect($reports[0]->phone)->toBe('79990000001');
expect($reports[0]->state)->toBe(SmsDeliveryState::DELIVERED);
expect($reports[0]->deliveredAt?->toDateTimeString())->toBe('2026-07-30 16:31:40');
expect($reports[0]->partCount)->toBe(2);
expect($reports[0]->providerCost)->toBe('3.4');
});
it('читает «принял, но не отправил» — тот самый случай живой пробы 30.07', function () {
Http::fake(['*' => Http::response(mtsDeliveryBody('44747239', [[
'msid' => '79990000002',
'status' => 'NotSent',
'date' => '2026-07-30T16:31:02',
'userDeliveryDate' => null,
'partCount' => 1,
'cost' => 0,
]]))]);
$reports = mtsDeliveryProvider()->fetchDelivery(['44747239']);
expect($reports[0]->state)->toBe(SmsDeliveryState::NOT_SENT);
expect($reports[0]->deliveredAt)->toBeNull();
expect($reports[0]->providerCost)->toBe('0');
});
it('читает «везу» и «не довёз» как разные судьбы', function () {
Http::fake(['*' => Http::response(['code' => 0, 'data' => [
['messageID' => '1', 'statuses' => [['msid' => '79990000003', 'status' => 'Sending']]],
['messageID' => '2', 'statuses' => [['msid' => '79990000004', 'status' => 'NotDelivered']]],
]])]);
$reports = mtsDeliveryProvider()->fetchDelivery(['1', '2']);
expect($reports[0]->state)->toBe(SmsDeliveryState::SENDING);
expect($reports[1]->state)->toBe(SmsDeliveryState::NOT_DELIVERED);
});
it('незнакомое слово оператора не угадывает, а отдаёт пустую судьбу и само слово', function () {
Http::fake(['*' => Http::response(mtsDeliveryBody('1', [[
'msid' => '79990000005',
'status' => 'СовершенноНовоеСлово',
'partCount' => 1,
]]))]);
$reports = mtsDeliveryProvider()->fetchDelivery(['1']);
expect($reports[0]->state)->toBeNull();
expect($reports[0]->rawState)->toBe('СовершенноНовоеСлово');
});
it('спрашивает номера сообщений одной строкой через запятую', function () {
Http::fake(['*' => Http::response(['code' => 0, 'data' => []])]);
mtsDeliveryProvider()->fetchDelivery(['1', '2', '3']);
Http::assertSent(fn ($request) => str_contains(urldecode($request->url()), 'messageIDs=1,2,3'));
});
it('пустой список никого не спрашивает вовсе', function () {
Http::fake(['*' => Http::response(['code' => 0, 'data' => []])]);
expect(mtsDeliveryProvider()->fetchDelivery([]))->toBe([]);
Http::assertNothingSent();
});
it('отказ МТС — не окончательный: судьбу всегда можно переспросить позже', function () {
Http::fake(['*' => Http::response('', 502)]);
try {
mtsDeliveryProvider()->fetchDelivery(['1']);
$this->fail('ожидали отказ канала');
} catch (SmsSendException $e) {
expect($e->terminal)->toBeFalse();
}
});