Skip to content

Commit df9d96b

Browse files
committed
bug symfony#57447 [Notifier] [Lox24] Fix request body format to JSON string (alebedev80)
This PR was squashed before being merged into the 7.1 branch. Discussion ---------- [Notifier] [Lox24] Fix request body format to JSON string | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | | License | MIT After lox24-notifier was release (version 7.1) i've found a bug. Request's header `Content-Type` changed to `application/x-www-form-urlencoded` from `application\json`. Issue was relate to array type of the body. I've changed it to JSON string and tested. Looks good. Please merge. Commits ------- 59f8331 [Notifier] [Lox24] Fix request body format to JSON string
2 parents 3c44ed8 + 59f8331 commit df9d96b

File tree

3 files changed

+63
-41
lines changed

3 files changed

+63
-41
lines changed

src/Symfony/Component/Notifier/Bridge/Lox24/Lox24Transport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ protected function doSend(MessageInterface $message): SentMessage
101101
'Content-Type' => 'application/json',
102102
'User-Agent' => 'LOX24 Symfony Notifier',
103103
],
104-
'body' => $body,
104+
'json' => $body,
105105
]);
106106

107107
try {

src/Symfony/Component/Notifier/Bridge/Lox24/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ DSN example
88
-----------
99

1010
```
11-
LOX24_DSN=lox24://USER:TOKEN@default?from=FROM&type=SERVICE_CODE&voice_lang=VOICE_LANGUAGE&delete_text=DELETE_TEXT&callback_data=CALLBACK_DATA
11+
LOX24_DSN=lox24://USER:TOKEN@default?from=FROM&type=TYPE&voice_lang=VOICE_LANGUAGE&delete_text=DELETE_TEXT&callback_data=CALLBACK_DATA
1212
```
1313

1414
where:

src/Symfony/Component/Notifier/Bridge/Lox24/Tests/Lox24TransportTest.php

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
use PHPUnit\Framework\MockObject\MockObject;
1312
use Symfony\Component\HttpClient\MockHttpClient;
13+
use Symfony\Component\HttpClient\Response\JsonMockResponse;
14+
use Symfony\Component\HttpClient\Response\MockResponse;
1415
use Symfony\Component\Notifier\Bridge\Lox24\Lox24Options;
1516
use Symfony\Component\Notifier\Bridge\Lox24\Lox24Transport;
1617
use Symfony\Component\Notifier\Bridge\Lox24\Type;
@@ -25,7 +26,6 @@
2526
use Symfony\Component\Notifier\Message\SmsMessage;
2627
use Symfony\Component\Notifier\Test\TransportTestCase;
2728
use Symfony\Contracts\HttpClient\HttpClientInterface;
28-
use Symfony\Contracts\HttpClient\ResponseInterface;
2929

3030
/**
3131
* @author Andrei Lebedev <[email protected]>
@@ -48,13 +48,6 @@ class Lox24TransportTest extends TransportTestCase
4848
'service_code' => 'direct',
4949
];
5050

51-
private MockObject|HttpClientInterface $client;
52-
53-
protected function setUp(): void
54-
{
55-
$this->client = $this->createMock(HttpClientInterface::class);
56-
}
57-
5851
public static function createTransport(?HttpClientInterface $client = null): Lox24Transport
5952
{
6053
return (new Lox24Transport('user', 'token', 'sender', ['type' => 'voice'], $client ?? new MockHttpClient()))->setHost('host.test');
@@ -102,30 +95,31 @@ public function testSendWithInvalidMessageType()
10295

10396
public function testMessageFromNotEmpty()
10497
{
105-
$this->assertRequestBody([
98+
$client = $this->mockHttpClient([
10699
'sender_id' => 'testFrom2',
107100
'phone' => '+1411111111',
108101
'text' => 'test text',
109102
'is_text_deleted' => false,
110103
'delivery_at' => 0,
111104
'service_code' => 'direct',
112105
], [], 201, ['uuid' => '123456']);
113-
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client);
106+
107+
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $client);
114108
$message = new SmsMessage('+1411111111', 'test text', 'testFrom2');
115109
$transport->send($message);
116110
}
117111

118112
public function testMessageFromEmpty()
119113
{
120-
$this->assertRequestBody([
114+
$client = $this->mockHttpClient([
121115
'sender_id' => 'testFrom',
122116
'phone' => '+1411111111',
123117
'text' => 'test text',
124118
'is_text_deleted' => false,
125119
'delivery_at' => 0,
126120
'service_code' => 'direct',
127121
], [], 201, ['uuid' => '123456']);
128-
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client);
122+
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $client);
129123
$message = new SmsMessage('+1411111111', 'test text');
130124
$transport->send($message);
131125
}
@@ -143,15 +137,15 @@ public function testMessageFromInvalid()
143137

144138
public function testOptionIsTextDeleted()
145139
{
146-
$this->assertRequestBody([
140+
$client = $this->mockHttpClient([
147141
'sender_id' => 'testFrom',
148142
'phone' => '+1411111111',
149143
'text' => 'test text',
150144
'is_text_deleted' => true,
151145
'delivery_at' => 0,
152146
'service_code' => 'direct',
153147
], [], 201, ['uuid' => '123456']);
154-
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client);
148+
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $client);
155149

156150
$options = (new Lox24Options())->deleteTextAfterSending(true);
157151
$message = new SmsMessage('+1411111111', 'test text');
@@ -162,15 +156,15 @@ public function testOptionIsTextDeleted()
162156

163157
public function testOptionDeliveryAtGreaterThanZero()
164158
{
165-
$this->assertRequestBody([
159+
$client = $this->mockHttpClient([
166160
'sender_id' => 'testFrom',
167161
'phone' => '+1411111111',
168162
'text' => 'test text',
169163
'is_text_deleted' => false,
170164
'delivery_at' => 1000000000,
171165
'service_code' => 'direct',
172166
], [], 201, ['uuid' => '123456']);
173-
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client);
167+
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $client);
174168

175169
$options = (new Lox24Options())->deliveryAt((new DateTimeImmutable())->setTimestamp(1000000000));
176170
$message = new SmsMessage('+1411111111', 'test text');
@@ -181,7 +175,7 @@ public function testOptionDeliveryAtGreaterThanZero()
181175

182176
public function testOptionVoiceLanguageSpanish()
183177
{
184-
$this->assertRequestBody([
178+
$client = $this->mockHttpClient([
185179
'sender_id' => 'testFrom',
186180
'phone' => '+1411111111',
187181
'text' => 'test text',
@@ -190,7 +184,7 @@ public function testOptionVoiceLanguageSpanish()
190184
'service_code' => 'text2speech',
191185
'voice_lang' => 'ES',
192186
], [], 201, ['uuid' => '123456']);
193-
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client);
187+
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $client);
194188

195189
$options = (new Lox24Options())
196190
->voiceLanguage(VoiceLanguage::Spanish)
@@ -203,15 +197,15 @@ public function testOptionVoiceLanguageSpanish()
203197

204198
public function testOptionVoiceLanguageAuto()
205199
{
206-
$this->assertRequestBody([
200+
$client = $this->mockHttpClient([
207201
'sender_id' => 'testFrom',
208202
'phone' => '+1411111111',
209203
'text' => 'test text',
210204
'is_text_deleted' => false,
211205
'delivery_at' => 0,
212206
'service_code' => 'text2speech',
213207
], [], 201, ['uuid' => '123456']);
214-
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client);
208+
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $client);
215209

216210
$options = (new Lox24Options())
217211
->voiceLanguage(VoiceLanguage::Auto)
@@ -224,7 +218,7 @@ public function testOptionVoiceLanguageAuto()
224218

225219
public function testOptionType()
226220
{
227-
$this->assertRequestBody([
221+
$client = $this->mockHttpClient([
228222
'sender_id' => 'testFrom',
229223
'phone' => '+1411111111',
230224
'text' => 'test text',
@@ -233,7 +227,7 @@ public function testOptionType()
233227
'service_code' => 'direct',
234228
], [], 201, ['uuid' => '123456']);
235229

236-
$transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $this->client);
230+
$transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $client);
237231

238232
$options = (new Lox24Options())->type(Type::Sms);
239233
$message = new SmsMessage('+1411111111', 'test text');
@@ -244,7 +238,7 @@ public function testOptionType()
244238

245239
public function testOptionCallbackData()
246240
{
247-
$this->assertRequestBody([
241+
$client = $this->mockHttpClient([
248242
'sender_id' => 'testFrom',
249243
'phone' => '+1411111111',
250244
'text' => 'test text',
@@ -254,7 +248,7 @@ public function testOptionCallbackData()
254248
'callback_data' => 'callback_data',
255249
], [], 201, ['uuid' => '123456']);
256250

257-
$transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $this->client);
251+
$transport = new Lox24Transport('user', 'token', 'testFrom', ['type' => 'voice'], $client);
258252

259253
$options = (new Lox24Options())->callbackData('callback_data');
260254
$message = new SmsMessage('+1411111111', 'test text');
@@ -270,7 +264,7 @@ public function testResponseStatusCodeNotEqual201()
270264
'Unable to send the SMS: "service_code: Service\'s code is invalid or unavailable.".'
271265
);
272266

273-
$this->assertRequestBody([
267+
$client = $this->mockHttpClient([
274268
'sender_id' => 'testFrom',
275269
'phone' => '+1411111111',
276270
'text' => 'test text',
@@ -294,28 +288,56 @@ public function testResponseStatusCodeNotEqual201()
294288
],
295289
);
296290

297-
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $this->client);
291+
$transport = new Lox24Transport('user', 'token', 'testFrom', [], $client);
298292

299293
$message = new SmsMessage('+1411111111', 'test text');
300294
$transport->send($message);
301295
}
302296

303-
private function assertRequestBody(
297+
public function mockHttpClient(
304298
array $bodyOverride = [],
305299
array $headersOverride = [],
306300
int $responseStatus = 200,
307301
array $responseContent = [],
308-
): void {
309-
$body = array_merge(self::REQUEST_BODY, $bodyOverride);
302+
): MockHttpClient {
303+
$body = json_encode(array_merge(self::REQUEST_BODY, $bodyOverride));
310304
$headers = array_merge(self::REQUEST_HEADERS, $headersOverride);
311-
$response = $this->createMock(ResponseInterface::class);
312-
$response->expects($this->once())->method('getStatusCode')->willReturn($responseStatus);
313-
$response->expects($this->once())->method('toArray')->willReturn($responseContent);
314-
$this->client->expects($this->once())
315-
->method('request')
316-
->with('POST', 'https://api.lox24.eu/sms', [
317-
'body' => $body,
318-
'headers' => $headers,
319-
])->willReturn($response);
305+
306+
$factory = function ($method, $url, $options) use (
307+
$body,
308+
$headers,
309+
$responseStatus,
310+
$responseContent
311+
): MockResponse {
312+
$this->assertSame('POST', $method);
313+
$this->assertSame('https://api.lox24.eu/sms', $url);
314+
$this->assertHeaders($headers, $options['headers']);
315+
$this->assertJsonStringEqualsJsonString($body, $options['body']);
316+
317+
return new JsonMockResponse($responseContent, [
318+
'http_code' => $responseStatus,
319+
'headers' => ['content-type' => 'application/json'],
320+
]);
321+
};
322+
323+
return new MockHttpClient($factory);
324+
}
325+
326+
private function assertHeaders(array $expected, array $headers): void
327+
{
328+
foreach ($this->normalizeHeaders($expected) as $expectedHeader) {
329+
$headerExists = in_array($expectedHeader, $headers, true);
330+
$this->assertTrue($headerExists, "Header '$expectedHeader' not found in request's headers");
331+
}
332+
}
333+
334+
private function normalizeHeaders(array $headers): array
335+
{
336+
$normalized = [];
337+
foreach ($headers as $key => $value) {
338+
$normalized[] = $key.': '.$value;
339+
}
340+
341+
return $normalized;
320342
}
321343
}

0 commit comments

Comments
 (0)