117 lines
4.8 KiB
PHP
117 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Sms;
|
|
|
|
use App\Sms\Entity\SmsLog;
|
|
use App\Sms\Message\SendSmsMessage;
|
|
use App\Sms\Provider\KavehNegarProvider;
|
|
use App\Sms\Provider\RanginehProvider;
|
|
use App\Sms\Repository\SmsLogRepository;
|
|
use App\Sms\Repository\SmsMessageTemplateRepository;
|
|
use App\Sms\Service\SmsService;
|
|
use App\Sms\Service\SmsTextResolver;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\Messenger\Envelope;
|
|
use Symfony\Component\Messenger\MessageBusInterface;
|
|
|
|
/**
|
|
* سیاست lookup-only: هیچ مسیری نباید به sms/send.json خام (provider->send) سقوط کند.
|
|
*/
|
|
class SmsServiceLookupOnlyTest extends TestCase
|
|
{
|
|
private KavehNegarProvider&MockObject $kavenegar;
|
|
private SmsLogRepository&MockObject $logRepo;
|
|
private MessageBusInterface&MockObject $bus;
|
|
private SmsMessageTemplateRepository&MockObject $messageTemplateRepo;
|
|
private SmsTextResolver&MockObject $textResolver;
|
|
private SmsService $service;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->kavenegar = $this->createMock(KavehNegarProvider::class);
|
|
$this->kavenegar->method('getName')->willReturn('kavenegar');
|
|
$this->logRepo = $this->createMock(SmsLogRepository::class);
|
|
$this->bus = $this->createMock(MessageBusInterface::class);
|
|
$this->messageTemplateRepo = $this->createMock(SmsMessageTemplateRepository::class);
|
|
$this->textResolver = $this->createMock(SmsTextResolver::class);
|
|
|
|
$this->service = new SmsService(
|
|
$this->kavenegar,
|
|
$this->createMock(RanginehProvider::class),
|
|
$this->logRepo,
|
|
$this->bus,
|
|
$this->messageTemplateRepo,
|
|
$this->textResolver,
|
|
$this->createMock(LoggerInterface::class),
|
|
);
|
|
}
|
|
|
|
public function testSendNowWithoutTemplateCodeRefusesRawSendAndLogsFailure(): void
|
|
{
|
|
$this->kavenegar->expects($this->never())->method('send');
|
|
$this->kavenegar->expects($this->never())->method('sendTemplate');
|
|
|
|
$captured = null;
|
|
$this->logRepo->expects($this->once())->method('save')
|
|
->willReturnCallback(function (SmsLog $log) use (&$captured) { $captured = $log; });
|
|
|
|
$msg = new SendSmsMessage('09120000000', 'hello', 'kavenegar', tag: SmsLog::TAG_GLOBAL);
|
|
$ok = $this->service->sendNow($msg);
|
|
|
|
$this->assertFalse($ok);
|
|
$this->assertNotNull($captured);
|
|
$this->assertFalse($captured->toArray()['success']);
|
|
}
|
|
|
|
public function testSendNowWithTemplateCodeUsesLookup(): void
|
|
{
|
|
$this->kavenegar->expects($this->never())->method('send');
|
|
$this->kavenegar->expects($this->once())->method('sendTemplate')
|
|
->with('09120000000', 'clinicpro-otp', ['token' => '1234'])
|
|
->willReturn(true);
|
|
$this->logRepo->expects($this->once())->method('save');
|
|
|
|
$msg = new SendSmsMessage(
|
|
'09120000000', 'code 1234', 'kavenegar',
|
|
templateVars: ['token' => '1234'], templateCode: 'clinicpro-otp', tag: SmsLog::TAG_OTP,
|
|
);
|
|
|
|
$this->assertTrue($this->service->sendNow($msg));
|
|
}
|
|
|
|
public function testDispatchTemplateForTagWithoutTemplateDoesNotEnqueueAndLogsFailure(): void
|
|
{
|
|
// TAG_GLOBAL در DEFAULTS نیست و در DB هم چیزی نداریم → باید رد شود، نه ارسال خام.
|
|
$this->messageTemplateRepo->method('findByTag')->willReturn(null);
|
|
$this->textResolver->method('resolve')->willReturn('any body');
|
|
$this->bus->expects($this->never())->method('dispatch');
|
|
$this->logRepo->expects($this->once())->method('save');
|
|
|
|
$this->service->dispatchTemplate(SmsLog::TAG_GLOBAL, '09120000000', ['x' => 'y']);
|
|
}
|
|
|
|
public function testDispatchTemplateForKnownTagEnqueuesWithTemplateCode(): void
|
|
{
|
|
// TAG_OTP در DEFAULTS الگو + token_map دارد → باید با templateCode به صف برود.
|
|
$this->messageTemplateRepo->method('findByTag')->willReturn(null);
|
|
$this->textResolver->method('resolve')->willReturn('کد شما: 1234');
|
|
|
|
$captured = null;
|
|
$this->bus->expects($this->once())->method('dispatch')
|
|
->willReturnCallback(function (SendSmsMessage $m) use (&$captured) {
|
|
$captured = $m;
|
|
return new Envelope($m);
|
|
});
|
|
$this->logRepo->expects($this->never())->method('save');
|
|
|
|
$this->service->dispatchTemplate(SmsLog::TAG_OTP, '09120000000', ['code' => '1234', 'site' => 'یزد']);
|
|
|
|
$this->assertNotNull($captured);
|
|
$this->assertSame('clinicpro-otp', $captured->templateCode);
|
|
$this->assertArrayHasKey('token', $captured->templateVars);
|
|
$this->assertSame('1234', $captured->templateVars['token']);
|
|
}
|
|
}
|