Browse code

Added README.md appinfo/info.xml appinfo/signature.json lib/Controller/AuthorApiController.php and the providers directory

DoubleBastionAdmin authored on 20/08/2022 16:33:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,375 @@
1
+<?php
2
+
3
+namespace Telnyx\HttpClient;
4
+
5
+/**
6
+ * @internal
7
+ * @covers \Telnyx\HttpClient\CurlClient
8
+ */
9
+final class CurlClientTest extends \Telnyx\TestCase
10
+{
11
+    /** @var \ReflectionProperty */
12
+    private $initialNetworkRetryDelayProperty;
13
+
14
+    /** @var \ReflectionProperty */
15
+    private $maxNetworkRetryDelayProperty;
16
+
17
+    /** @var float */
18
+    private $origInitialNetworkRetryDelay;
19
+
20
+    /** @var int */
21
+    private $origMaxNetworkRetries;
22
+
23
+    /** @var float */
24
+    private $origMaxNetworkRetryDelay;
25
+
26
+    /** @var \ReflectionMethod */
27
+    private $sleepTimeMethod;
28
+
29
+    /** @var \ReflectionMethod */
30
+    private $shouldRetryMethod;
31
+
32
+    /**
33
+     * @before
34
+     */
35
+    public function saveOriginalNetworkValues()
36
+    {
37
+        $this->origMaxNetworkRetries = \Telnyx\Telnyx::getMaxNetworkRetries();
38
+        $this->origMaxNetworkRetryDelay = \Telnyx\Telnyx::getMaxNetworkRetryDelay();
39
+        $this->origInitialNetworkRetryDelay = \Telnyx\Telnyx::getInitialNetworkRetryDelay();
40
+    }
41
+
42
+    /**
43
+     * @before
44
+     */
45
+    public function setUpReflectors()
46
+    {
47
+        $telnyxReflector = new \ReflectionClass('\Telnyx\Telnyx');
48
+
49
+        $this->maxNetworkRetryDelayProperty = $telnyxReflector->getProperty('maxNetworkRetryDelay');
50
+        $this->maxNetworkRetryDelayProperty->setAccessible(true);
51
+
52
+        $this->initialNetworkRetryDelayProperty = $telnyxReflector->getProperty('initialNetworkRetryDelay');
53
+        $this->initialNetworkRetryDelayProperty->setAccessible(true);
54
+
55
+        $curlClientReflector = new \ReflectionClass('\Telnyx\HttpClient\CurlClient');
56
+
57
+        $this->shouldRetryMethod = $curlClientReflector->getMethod('shouldRetry');
58
+        $this->shouldRetryMethod->setAccessible(true);
59
+
60
+        $this->sleepTimeMethod = $curlClientReflector->getMethod('sleepTime');
61
+        $this->sleepTimeMethod->setAccessible(true);
62
+    }
63
+
64
+    /**
65
+     * @after
66
+     */
67
+    public function restoreOriginalNetworkValues()
68
+    {
69
+        \Telnyx\Telnyx::setMaxNetworkRetries($this->origMaxNetworkRetries);
70
+        $this->setMaxNetworkRetryDelay($this->origMaxNetworkRetryDelay);
71
+        $this->setInitialNetworkRetryDelay($this->origInitialNetworkRetryDelay);
72
+    }
73
+
74
+    private function setMaxNetworkRetryDelay($maxNetworkRetryDelay)
75
+    {
76
+        $this->maxNetworkRetryDelayProperty->setValue(null, $maxNetworkRetryDelay);
77
+    }
78
+
79
+    private function setInitialNetworkRetryDelay($initialNetworkRetryDelay)
80
+    {
81
+        $this->initialNetworkRetryDelayProperty->setValue(null, $initialNetworkRetryDelay);
82
+    }
83
+
84
+    private function createFakeRandomGenerator($returnValue = 1.0)
85
+    {
86
+        $fakeRandomGenerator = $this->createMock('\Telnyx\Util\RandomGenerator');
87
+        $fakeRandomGenerator->method('randFloat')->willReturn($returnValue);
88
+
89
+        return $fakeRandomGenerator;
90
+    }
91
+
92
+    public function testTimeout()
93
+    {
94
+        $curl = new CurlClient();
95
+        static::assertSame(CurlClient::DEFAULT_TIMEOUT, $curl->getTimeout());
96
+        static::assertSame(CurlClient::DEFAULT_CONNECT_TIMEOUT, $curl->getConnectTimeout());
97
+
98
+        // implicitly tests whether we're returning the CurlClient instance
99
+        $curl = $curl->setConnectTimeout(1)->setTimeout(10);
100
+        static::assertSame(1, $curl->getConnectTimeout());
101
+        static::assertSame(10, $curl->getTimeout());
102
+
103
+        $curl->setTimeout(-1);
104
+        $curl->setConnectTimeout(-999);
105
+        static::assertSame(0, $curl->getTimeout());
106
+        static::assertSame(0, $curl->getConnectTimeout());
107
+    }
108
+
109
+    public function testUserAgentInfo()
110
+    {
111
+        $curl = new CurlClient();
112
+        $uaInfo = $curl->getUserAgentInfo();
113
+        static::assertNotNull($uaInfo);
114
+        static::assertNotNull($uaInfo['httplib']);
115
+        static::assertNotNull($uaInfo['ssllib']);
116
+    }
117
+
118
+    public function testDefaultOptions()
119
+    {
120
+        // make sure options array loads/saves properly
121
+        $optionsArray = [\CURLOPT_PROXY => 'localhost:80'];
122
+        $withOptionsArray = new CurlClient($optionsArray);
123
+        static::assertSame($withOptionsArray->getDefaultOptions(), $optionsArray);
124
+
125
+        // make sure closure-based options work properly, including argument passing
126
+        $ref = null;
127
+        $withClosure = new CurlClient(function ($method, $absUrl, $headers, $params, $hasFile) use (&$ref) {
128
+            $ref = \func_get_args();
129
+
130
+            return [];
131
+        });
132
+
133
+        $withClosure->request('get', 'https://httpbin.org/status/200', [], [], false);
134
+        static::assertSame($ref, ['get', 'https://httpbin.org/status/200', [], [], false]);
135
+
136
+        // this is the last test case that will run, since it'll throw an exception at the end
137
+        $withBadClosure = new CurlClient(function () {
138
+            return 'thisShouldNotWork';
139
+        });
140
+        $this->expectException('Telnyx\Exception\UnexpectedValueException');
141
+        $this->expectExceptionMessage('Non-array value returned by defaultOptions CurlClient callback');
142
+        $withBadClosure->request('get', 'https://httpbin.org/status/200', [], [], false);
143
+    }
144
+
145
+    public function testSslOption()
146
+    {
147
+        // make sure options array loads/saves properly
148
+        $optionsArray = [\CURLOPT_SSLVERSION => \CURL_SSLVERSION_TLSv1];
149
+        $withOptionsArray = new CurlClient($optionsArray);
150
+        static::assertSame($withOptionsArray->getDefaultOptions(), $optionsArray);
151
+    }
152
+
153
+    public function testShouldRetryOnTimeout()
154
+    {
155
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
156
+
157
+        $curlClient = new CurlClient();
158
+
159
+        static::assertTrue($this->shouldRetryMethod->invoke($curlClient, \CURLE_OPERATION_TIMEOUTED, 0, [], 0));
160
+    }
161
+
162
+    public function testShouldRetryOnConnectionFailure()
163
+    {
164
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
165
+
166
+        $curlClient = new CurlClient();
167
+
168
+        static::assertTrue($this->shouldRetryMethod->invoke($curlClient, \CURLE_COULDNT_CONNECT, 0, [], 0));
169
+    }
170
+
171
+    public function testShouldRetryOnConflict()
172
+    {
173
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
174
+
175
+        $curlClient = new CurlClient();
176
+
177
+        static::assertTrue($this->shouldRetryMethod->invoke($curlClient, 0, 409, [], 0));
178
+    }
179
+
180
+    public function testShouldNotRetryOn429()
181
+    {
182
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
183
+
184
+        $curlClient = new CurlClient();
185
+
186
+        static::assertFalse($this->shouldRetryMethod->invoke($curlClient, 0, 429, [], 0));
187
+    }
188
+
189
+    public function testShouldRetryOn500()
190
+    {
191
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
192
+
193
+        $curlClient = new CurlClient();
194
+
195
+        static::assertTrue($this->shouldRetryMethod->invoke($curlClient, 0, 500, [], 0));
196
+    }
197
+
198
+    public function testShouldRetryOn503()
199
+    {
200
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
201
+
202
+        $curlClient = new CurlClient();
203
+
204
+        static::assertTrue($this->shouldRetryMethod->invoke($curlClient, 0, 503, [], 0));
205
+    }
206
+
207
+    public function testShouldRetryOnStripeShouldRetryTrue()
208
+    {
209
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
210
+
211
+        $curlClient = new CurlClient();
212
+
213
+        static::assertFalse($this->shouldRetryMethod->invoke($curlClient, 0, 400, [], 0));
214
+        static::assertTrue($this->shouldRetryMethod->invoke($curlClient, 0, 400, ['telnyx-should-retry' => 'true'], 0));
215
+    }
216
+
217
+    public function testShouldNotRetryOnStripeShouldRetryFalse()
218
+    {
219
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
220
+
221
+        $curlClient = new CurlClient();
222
+
223
+        static::assertTrue($this->shouldRetryMethod->invoke($curlClient, 0, 500, [], 0));
224
+        static::assertFalse($this->shouldRetryMethod->invoke($curlClient, 0, 500, ['telnyx-should-retry' => 'false'], 0));
225
+    }
226
+
227
+    public function testShouldNotRetryAtMaximumCount()
228
+    {
229
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
230
+
231
+        $curlClient = new CurlClient();
232
+
233
+        static::assertFalse($this->shouldRetryMethod->invoke($curlClient, 0, 0, [], \Telnyx\Telnyx::getMaxNetworkRetries()));
234
+    }
235
+
236
+    public function testShouldNotRetryOnCertValidationError()
237
+    {
238
+        \Telnyx\Telnyx::setMaxNetworkRetries(2);
239
+
240
+        $curlClient = new CurlClient();
241
+
242
+        static::assertFalse($this->shouldRetryMethod->invoke($curlClient, \CURLE_SSL_PEER_CERTIFICATE, -1, [], 0));
243
+    }
244
+
245
+    public function testSleepTimeShouldGrowExponentially()
246
+    {
247
+        $this->setMaxNetworkRetryDelay(999.0);
248
+
249
+        $curlClient = new CurlClient(null, $this->createFakeRandomGenerator());
250
+
251
+        static::assertSame(
252
+            \Telnyx\Telnyx::getInitialNetworkRetryDelay() * 1,
253
+            $this->sleepTimeMethod->invoke($curlClient, 1, [])
254
+        );
255
+        static::assertSame(
256
+            \Telnyx\Telnyx::getInitialNetworkRetryDelay() * 2,
257
+            $this->sleepTimeMethod->invoke($curlClient, 2, [])
258
+        );
259
+        static::assertSame(
260
+            \Telnyx\Telnyx::getInitialNetworkRetryDelay() * 4,
261
+            $this->sleepTimeMethod->invoke($curlClient, 3, [])
262
+        );
263
+        static::assertSame(
264
+            \Telnyx\Telnyx::getInitialNetworkRetryDelay() * 8,
265
+            $this->sleepTimeMethod->invoke($curlClient, 4, [])
266
+        );
267
+    }
268
+
269
+    public function testSleepTimeShouldEnforceMaxNetworkRetryDelay()
270
+    {
271
+        $this->setInitialNetworkRetryDelay(1.0);
272
+        $this->setMaxNetworkRetryDelay(2);
273
+
274
+        $curlClient = new CurlClient(null, $this->createFakeRandomGenerator());
275
+
276
+        static::assertSame(1.0, $this->sleepTimeMethod->invoke($curlClient, 1, []));
277
+        static::assertSame(2.0, $this->sleepTimeMethod->invoke($curlClient, 2, []));
278
+        static::assertSame(2.0, $this->sleepTimeMethod->invoke($curlClient, 3, []));
279
+        static::assertSame(2.0, $this->sleepTimeMethod->invoke($curlClient, 4, []));
280
+    }
281
+
282
+    public function testSleepTimeShouldRespectRetryAfter()
283
+    {
284
+        $this->setInitialNetworkRetryDelay(1.0);
285
+        $this->setMaxNetworkRetryDelay(2.0);
286
+
287
+        $curlClient = new CurlClient(null, $this->createFakeRandomGenerator());
288
+
289
+        // Uses max of default and header.
290
+        static::assertSame(10.0, $this->sleepTimeMethod->invoke($curlClient, 1, ['retry-after' => '10']));
291
+        static::assertSame(2.0, $this->sleepTimeMethod->invoke($curlClient, 2, ['retry-after' => '1']));
292
+
293
+        // Ignores excessively large values.
294
+        static::assertSame(2.0, $this->sleepTimeMethod->invoke($curlClient, 2, ['retry-after' => '100']));
295
+    }
296
+
297
+    public function testSleepTimeShouldAddSomeRandomness()
298
+    {
299
+        $randomValue = 0.8;
300
+        $this->setInitialNetworkRetryDelay(1.0);
301
+        $this->setMaxNetworkRetryDelay(8.0);
302
+
303
+        $curlClient = new CurlClient(null, $this->createFakeRandomGenerator($randomValue));
304
+
305
+        $baseValue = \Telnyx\Telnyx::getInitialNetworkRetryDelay() * (0.5 * (1 + $randomValue));
306
+
307
+        // the initial value cannot be smaller than the base,
308
+        // so the randomness is ignored
309
+        static::assertSame(\Telnyx\Telnyx::getInitialNetworkRetryDelay(), $this->sleepTimeMethod->invoke($curlClient, 1, []));
310
+
311
+        // after the first one, the randomness is applied
312
+        static::assertSame($baseValue * 2, $this->sleepTimeMethod->invoke($curlClient, 2, []));
313
+        static::assertSame($baseValue * 4, $this->sleepTimeMethod->invoke($curlClient, 3, []));
314
+        static::assertSame($baseValue * 8, $this->sleepTimeMethod->invoke($curlClient, 4, []));
315
+    }
316
+
317
+    public function testResponseHeadersCaseInsensitive()
318
+    {
319
+        $profiles = \Telnyx\MessagingProfile::all();
320
+
321
+        $headers = $profiles->getLastResponse()->headers;
322
+        static::assertNotNull($headers['request-id']);
323
+        static::assertSame($headers['request-id'], $headers['Request-Id']);
324
+    }
325
+
326
+    public function testSetRequestStatusCallback()
327
+    {
328
+        try {
329
+            $called = false;
330
+
331
+            $curl = new CurlClient();
332
+            $curl->setRequestStatusCallback(function ($rbody, $rcode, $rheaders, $errno, $message, $willBeRetried, $numRetries) use (&$called) {
333
+                $called = true;
334
+
335
+                $this->assertInternalType('string', $rbody);
336
+                $this->assertSame(200, $rcode);
337
+                $this->assertSame(0, $errno);
338
+                $this->assertNull($message);
339
+                $this->assertFalse($willBeRetried);
340
+                $this->assertSame(0, $numRetries);
341
+            });
342
+
343
+            \Telnyx\ApiRequestor::setHttpClient($curl);
344
+
345
+            \Telnyx\MessagingProfile::all();
346
+
347
+            static::assertTrue($called);
348
+        } finally {
349
+            \Telnyx\ApiRequestor::setHttpClient(null);
350
+        }
351
+    }
352
+
353
+    public function testInvalidMethod() {
354
+        $curl = new CurlClient();
355
+
356
+        $this->expectException('Telnyx\Exception\UnexpectedValueException');
357
+        $this->expectExceptionMessage('Unrecognized method invalidmethod');
358
+
359
+        $curl->request('invalidmethod', 'https://httpbin.org/status/200', [], [], false);
360
+
361
+    }
362
+    public function testGetSets() {
363
+        $curl = new CurlClient();
364
+
365
+        $curl->setEnablePersistentConnections(false);
366
+        static::assertSame(false, $curl->getEnablePersistentConnections());
367
+        $curl->setEnablePersistentConnections(true);
368
+        static::assertSame(true, $curl->getEnablePersistentConnections());
369
+
370
+        $curl->setEnableHttp2(false);
371
+        static::assertSame(false, $curl->getEnableHttp2());
372
+        $curl->setEnableHttp2(true);
373
+        static::assertSame(true, $curl->getEnableHttp2());
374
+    }
375
+}