From 59f83312daa5bdf3cd934b4285eece0ebcdeabcd Mon Sep 17 00:00:00 2001 From: Andrey Lebedev Date: Tue, 18 Jun 2024 19:38:55 +0400 Subject: [PATCH] [Notifier] [Lox24] Fix request body format to JSON string --- .../Notifier/Bridge/Lox24/Lox24Transport.php | 2 +- .../Component/Notifier/Bridge/Lox24/README.md | 2 +- .../Bridge/Lox24/Tests/Lox24TransportTest.php | 100 +++++++++++------- 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/src/Symfony/Component/Notifier/Bridge/Lox24/Lox24Transport.php b/src/Symfony/Component/Notifier/Bridge/Lox24/Lox24Transport.php index 31c71c8d9c6a6..19ac34b5edaf4 100644 --- a/src/Symfony/Component/Notifier/Bridge/Lox24/Lox24Transport.php +++ b/src/Symfony/Component/Notifier/Bridge/Lox24/Lox24Transport.php @@ -101,7 +101,7 @@ protected function doSend(MessageInterface $message): SentMessage 'Content-Type' => 'application/json', 'User-Agent' => 'LOX24 Symfony Notifier', ], - 'body' => $body, + 'json' => $body, ]); try { diff --git a/src/Symfony/Component/Notifier/Bridge/Lox24/README.md b/src/Symfony/Component/Notifier/Bridge/Lox24/README.md index 8d84187fcf46a..5a02bc10a2aa3 100644 --- a/src/Symfony/Component/Notifier/Bridge/Lox24/README.md +++ b/src/Symfony/Component/Notifier/Bridge/Lox24/README.md @@ -8,7 +8,7 @@ DSN example ----------- ``` -LOX24_DSN=lox24://USER:TOKEN@default?from=FROM&type=SERVICE_CODE&voice_lang=VOICE_LANGUAGE&delete_text=DELETE_TEXT&callback_data=CALLBACK_DATA +LOX24_DSN=lox24://USER:TOKEN@default?from=FROM&type=TYPE&voice_lang=VOICE_LANGUAGE&delete_text=DELETE_TEXT&callback_data=CALLBACK_DATA ``` where: diff --git a/src/Symfony/Component/Notifier/Bridge/Lox24/Tests/Lox24TransportTest.php b/src/Symfony/Component/Notifier/Bridge/Lox24/Tests/Lox24TransportTest.php index 3db43acbcdcc3..f24fc9b31c7e4 100644 --- a/src/Symfony/Component/Notifier/Bridge/Lox24/Tests/Lox24TransportTest.php +++ b/src/Symfony/Component/Notifier/Bridge/Lox24/Tests/Lox24TransportTest.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Response\JsonMockResponse; +use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\Notifier\Bridge\Lox24\Lox24Options; use Symfony\Component\Notifier\Bridge\Lox24\Lox24Transport; use Symfony\Component\Notifier\Bridge\Lox24\Type; @@ -25,7 +26,6 @@ use Symfony\Component\Notifier\Message\SmsMessage; use Symfony\Component\Notifier\Test\TransportTestCase; use Symfony\Contracts\HttpClient\HttpClientInterface; -use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Andrei Lebedev @@ -48,13 +48,6 @@ class Lox24TransportTest extends TransportTestCase 'service_code' => 'direct', ]; - private MockObject|HttpClientInterface $client; - - protected function setUp(): void - { - $this->client = $this->createMock(HttpClientInterface::class); - } - public static function createTransport(?HttpClientInterface $client = null): Lox24Transport { return (new Lox24Transport('user', 'token', 'sender', ['type' => 'voice'], $client ?? new MockHttpClient()))->setHost('host.test'); @@ -102,7 +95,7 @@ public function testSendWithInvalidMessageType() public function testMessageFromNotEmpty() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom2', 'phone' => '+1411111111', 'text' => 'test text', @@ -110,14 +103,15 @@ public function testMessageFromNotEmpty() 'delivery_at' => 0, 'service_code' => 'direct', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client); + + $transport = new Lox24Transport('user', 'token', 'testFrom', [], $client); $message = new SmsMessage('+1411111111', 'test text', 'testFrom2'); $transport->send($message); } public function testMessageFromEmpty() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -125,7 +119,7 @@ public function testMessageFromEmpty() 'delivery_at' => 0, 'service_code' => 'direct', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', [], $client); $message = new SmsMessage('+1411111111', 'test text'); $transport->send($message); } @@ -143,7 +137,7 @@ public function testMessageFromInvalid() public function testOptionIsTextDeleted() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -151,7 +145,7 @@ public function testOptionIsTextDeleted() 'delivery_at' => 0, 'service_code' => 'direct', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', [], $client); $options = (new Lox24Options())->deleteTextAfterSending(true); $message = new SmsMessage('+1411111111', 'test text'); @@ -162,7 +156,7 @@ public function testOptionIsTextDeleted() public function testOptionDeliveryAtGreaterThanZero() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -170,7 +164,7 @@ public function testOptionDeliveryAtGreaterThanZero() 'delivery_at' => 1000000000, 'service_code' => 'direct', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', [], $client); $options = (new Lox24Options())->deliveryAt((new DateTimeImmutable())->setTimestamp(1000000000)); $message = new SmsMessage('+1411111111', 'test text'); @@ -181,7 +175,7 @@ public function testOptionDeliveryAtGreaterThanZero() public function testOptionVoiceLanguageSpanish() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -190,7 +184,7 @@ public function testOptionVoiceLanguageSpanish() 'service_code' => 'text2speech', 'voice_lang' => 'ES', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', [], $client); $options = (new Lox24Options()) ->voiceLanguage(VoiceLanguage::Spanish) @@ -203,7 +197,7 @@ public function testOptionVoiceLanguageSpanish() public function testOptionVoiceLanguageAuto() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -211,7 +205,7 @@ public function testOptionVoiceLanguageAuto() 'delivery_at' => 0, 'service_code' => 'text2speech', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', [], $client); $options = (new Lox24Options()) ->voiceLanguage(VoiceLanguage::Auto) @@ -224,7 +218,7 @@ public function testOptionVoiceLanguageAuto() public function testOptionType() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -233,7 +227,7 @@ public function testOptionType() 'service_code' => 'direct', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $client); $options = (new Lox24Options())->type(Type::Sms); $message = new SmsMessage('+1411111111', 'test text'); @@ -244,7 +238,7 @@ public function testOptionType() public function testOptionCallbackData() { - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -254,7 +248,7 @@ public function testOptionCallbackData() 'callback_data' => 'callback_data', ], [], 201, ['uuid' => '123456']); - $transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $client); $options = (new Lox24Options())->callbackData('callback_data'); $message = new SmsMessage('+1411111111', 'test text'); @@ -270,7 +264,7 @@ public function testResponseStatusCodeNotEqual201() 'Unable to send the SMS: "service_code: Service\'s code is invalid or unavailable.".' ); - $this->assertRequestBody([ + $client = $this->mockHttpClient([ 'sender_id' => 'testFrom', 'phone' => '+1411111111', 'text' => 'test text', @@ -294,28 +288,56 @@ public function testResponseStatusCodeNotEqual201() ], ); - $transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client); + $transport = new Lox24Transport('user', 'token', 'testFrom', [], $client); $message = new SmsMessage('+1411111111', 'test text'); $transport->send($message); } - private function assertRequestBody( + public function mockHttpClient( array $bodyOverride = [], array $headersOverride = [], int $responseStatus = 200, array $responseContent = [], - ): void { - $body = array_merge(self::REQUEST_BODY, $bodyOverride); + ): MockHttpClient { + $body = json_encode(array_merge(self::REQUEST_BODY, $bodyOverride)); $headers = array_merge(self::REQUEST_HEADERS, $headersOverride); - $response = $this->createMock(ResponseInterface::class); - $response->expects($this->once())->method('getStatusCode')->willReturn($responseStatus); - $response->expects($this->once())->method('toArray')->willReturn($responseContent); - $this->client->expects($this->once()) - ->method('request') - ->with('POST', 'https://api.lox24.eu/sms', [ - 'body' => $body, - 'headers' => $headers, - ])->willReturn($response); + + $factory = function ($method, $url, $options) use ( + $body, + $headers, + $responseStatus, + $responseContent + ): MockResponse { + $this->assertSame('POST', $method); + $this->assertSame('https://api.lox24.eu/sms', $url); + $this->assertHeaders($headers, $options['headers']); + $this->assertJsonStringEqualsJsonString($body, $options['body']); + + return new JsonMockResponse($responseContent, [ + 'http_code' => $responseStatus, + 'headers' => ['content-type' => 'application/json'], + ]); + }; + + return new MockHttpClient($factory); + } + + private function assertHeaders(array $expected, array $headers): void + { + foreach ($this->normalizeHeaders($expected) as $expectedHeader) { + $headerExists = in_array($expectedHeader, $headers, true); + $this->assertTrue($headerExists, "Header '$expectedHeader' not found in request's headers"); + } + } + + private function normalizeHeaders(array $headers): array + { + $normalized = []; + foreach ($headers as $key => $value) { + $normalized[] = $key.': '.$value; + } + + return $normalized; } }