/
home
/
sjslayjy
/
public_html
/
theweavenest
/
vendor
/
rmccue
/
requests
/
tests
/
Upload File
HOME
<?php namespace WpOrg\Requests\Tests; use ArrayIterator; use EmptyIterator; use ReflectionProperty; use stdClass; use WpOrg\Requests\Capability; use WpOrg\Requests\Exception; use WpOrg\Requests\Exception\InvalidArgument; use WpOrg\Requests\Iri; use WpOrg\Requests\Requests; use WpOrg\Requests\Response\Headers; use WpOrg\Requests\Tests\Fixtures\ArrayAccessibleObject; use WpOrg\Requests\Tests\Fixtures\RawTransportMock; use WpOrg\Requests\Tests\Fixtures\StringableObject; use WpOrg\Requests\Tests\Fixtures\TestTransportMock; use WpOrg\Requests\Tests\Fixtures\TransportMock; final class RequestsTest extends TestCase { /** * Tests receiving an exception when the constructor received an invalid input type as `$url`. * * @dataProvider dataRequestInvalidUrl * * @covers \WpOrg\Requests\Requests::request * * @param mixed $input Invalid parameter input. * * @return void */ public function testRequestInvalidUrl($input) { $this->expectException(InvalidArgument::class); $this->expectExceptionMessage('Argument #1 ($url) must be of type string|Stringable'); Requests::request($input); } /** * Data Provider. * * @return array */ public function dataRequestInvalidUrl() { return [ 'null' => [null], 'array' => [[$this->httpbin('/')]], 'non-stringable object' => [new stdClass('name')], ]; } /** * Tests receiving an exception when the request() method received an invalid input type as `$type`. * * @dataProvider dataInvalidTypeNotString * * @covers \WpOrg\Requests\Requests::request * * @param mixed $input Invalid parameter input. * * @return void */ public function testRequestInvalidType($input) { $this->expectException(InvalidArgument::class); $this->expectExceptionMessage('Argument #4 ($type) must be of type string'); Requests::request('/', [], [], $input); } /** * Data Provider. * * @return array */ public function dataInvalidTypeNotString() { return [ 'null' => [null], 'stringable object' => [new StringableObject('type')], ]; } /** * Tests receiving an exception when the request() method received an invalid input type as `$options`. * * @dataProvider dataInvalidTypeNotArray * * @covers \WpOrg\Requests\Requests::request * * @param mixed $input Invalid parameter input. * * @return void */ public function testRequestInvalidOptions($input) { $this->expectException(InvalidArgument::class); $this->expectExceptionMessage('Argument #5 ($options) must be of type array'); Requests::request('/', [], [], Requests::GET, $input); } /** * Tests receiving an exception when the request_multiple() method received an invalid input type as `$requests`. * * @dataProvider dataRequestMultipleInvalidRequests * * @covers \WpOrg\Requests\Requests::request_multiple * * @param mixed $input Invalid parameter input. * * @return void */ public function testRequestMultipleInvalidRequests($input) { $this->expectException(InvalidArgument::class); $this->expectExceptionMessage('Argument #1 ($requests) must be of type array|ArrayAccess&Traversable'); Requests::request_multiple($input); } /** * Data Provider. * * @return array */ public function dataRequestMultipleInvalidRequests() { return [ 'null' => [null], 'text string' => ['array'], 'iterator object without array access' => [new EmptyIterator()], 'array accessible object not iterable' => [new ArrayAccessibleObject([1, 2, 3])], ]; } /** * Tests receiving an exception when the request_multiple() method received an invalid input type as `$option`. * * @dataProvider dataInvalidTypeNotArray * * @covers \WpOrg\Requests\Requests::request_multiple * * @param mixed $input Invalid parameter input. * * @return void */ public function testRequestMultipleInvalidOptions($input) { $this->expectException(InvalidArgument::class); $this->expectExceptionMessage('Argument #2 ($options) must be of type array'); Requests::request_multiple([], $input); } /** * Data Provider. * * @return array */ public function dataInvalidTypeNotArray() { return [ 'null' => [null], 'array accessible object' => [new ArrayAccessibleObject([])], ]; } public function testInvalidProtocol() { $this->expectException(Exception::class); $this->expectExceptionMessage('Only HTTP(S) requests are handled'); Requests::request('ftp://128.0.0.1/'); } public function testDefaultTransport() { $request = Requests::get(new Iri($this->httpbin('/get'))); $this->assertSame(200, $request->status_code); } /** * Standard response header parsing */ public function testHeaderParsing() { $transport = new RawTransportMock(); $transport->data = "HTTP/1.0 200 OK\r\n" . "Host: localhost\r\n" . "Host: ambiguous\r\n" . "Nospace:here\r\n" . "Muchspace: there \r\n" . "Empty:\r\n" . "Empty2: \r\n" . "Folded: one\r\n" . "\ttwo\r\n" . " three\r\n\r\n" . "stop\r\n"; $options = [ 'transport' => $transport, ]; $response = Requests::get('http://example.com/', [], $options); $expected = new Headers(); $expected['host'] = 'localhost,ambiguous'; $expected['nospace'] = 'here'; $expected['muchspace'] = 'there'; $expected['empty'] = ''; $expected['empty2'] = ''; $expected['folded'] = 'one two three'; foreach ($expected as $key => $value) { $this->assertSame($value, $response->headers[$key]); } foreach ($response->headers as $key => $value) { $this->assertSame($value, $expected[$key]); } } public function testProtocolVersionParsing() { $transport = new RawTransportMock(); $transport->data = "HTTP/1.0 200 OK\r\n" . "Host: localhost\r\n\r\n"; $options = [ 'transport' => $transport, ]; $response = Requests::get('http://example.com/', [], $options); $this->assertSame(1.0, $response->protocol_version); } public function testRawAccess() { $transport = new RawTransportMock(); $transport->data = "HTTP/1.0 200 OK\r\n" . "Host: localhost\r\n\r\n" . 'Test'; $options = [ 'transport' => $transport, ]; $response = Requests::get('http://example.com/', [], $options); $this->assertSame($transport->data, $response->raw); } /** * Headers with only \n delimiting should be treated as if they're \r\n */ public function testHeaderOnlyLF() { $transport = new RawTransportMock(); $transport->data = "HTTP/1.0 200 OK\r\nTest: value\nAnother-Test: value\r\n\r\n"; $options = [ 'transport' => $transport, ]; $response = Requests::get('http://example.com/', [], $options); $this->assertSame('value', $response->headers['test']); $this->assertSame('value', $response->headers['another-test']); } /** * Check that invalid protocols are not accepted * * We do not support HTTP/0.9. If this is really an issue for you, file a * new issue, and update your server/proxy to support a proper protocol. */ public function testInvalidProtocolVersion() { $transport = new RawTransportMock(); $transport->data = "HTTP/0.9 200 OK\r\n\r\n<p>Test"; $options = [ 'transport' => $transport, ]; $this->expectException(Exception::class); $this->expectExceptionMessage('Response could not be parsed'); Requests::get('http://example.com/', [], $options); } /** * HTTP/0.9 also appears to use a single CRLF instead of two. */ public function testSingleCRLFSeparator() { $transport = new RawTransportMock(); $transport->data = "HTTP/0.9 200 OK\r\n<p>Test"; $options = [ 'transport' => $transport, ]; $this->expectException(Exception::class); $this->expectExceptionMessage('Missing header/body separator'); Requests::get('http://example.com/', [], $options); } public function testInvalidStatus() { $transport = new RawTransportMock(); $transport->data = "HTTP/1.1 OK\r\nTest: value\nAnother-Test: value\r\n\r\nTest"; $options = [ 'transport' => $transport, ]; $this->expectException(Exception::class); $this->expectExceptionMessage('Response could not be parsed'); Requests::get('http://example.com/', [], $options); } public function test30xWithoutLocation() { $transport = new TransportMock(); $transport->code = 302; $options = [ 'transport' => $transport, ]; $response = Requests::get('http://example.com/', [], $options); $this->assertSame(302, $response->status_code); $this->assertSame(0, $response->redirects); } public function testTimeoutException() { $options = ['timeout' => 0.5]; $this->expectException(Exception::class); $this->expectExceptionMessage('timed out'); Requests::get($this->httpbin('/delay/3'), [], $options); } /** * @covers \WpOrg\Requests\Requests::has_capabilities */ public function testHasCapabilitiesSucceedsForDetectingSsl() { if (!extension_loaded('curl') && !extension_loaded('openssl')) { $this->markTestSkipped('Testing for SSL requires either the curl or the openssl extension'); } $this->assertTrue(Requests::has_capabilities([Capability::SSL => true])); } /** * @covers \WpOrg\Requests\Requests::has_capabilities */ public function testHasCapabilitiesFailsForUnsupportedCapabilities() { $transports = new ReflectionProperty(Requests::class, 'transports'); $transports->setAccessible(true); $transports->setValue(null, [TestTransportMock::class]); $result = Requests::has_capabilities(['time-travel' => true]); $transports->setValue(null, []); $transports->setAccessible(false); $this->assertFalse($result); } /** * Tests setting a custom certificate path with valid data types (though potentially not a valid path). * * @dataProvider dataSetCertificatePathValidData * * @covers \WpOrg\Requests\Requests::set_certificate_path * * @param mixed $input Valid input. * * @return void */ public function testSetCertificatePathValidData($input) { Requests::set_certificate_path($input); $this->assertSame($input, Requests::get_certificate_path()); } /** * Data Provider. * * @return array */ public function dataSetCertificatePathValidData() { return [ 'boolean false' => [false], 'boolean true' => [true], 'string' => ['path/to/file.pem'], 'stringable object' => [new StringableObject('path/to/file.pem')], ]; } /** * Tests receiving an exception when an invalid input type is passed as `$path` to the set_certificate_path() method. * * @dataProvider dataSetCertificatePathInvalidData * * @covers \WpOrg\Requests\Requests::set_certificate_path * * @param mixed $input Invalid input. * * @return void */ public function testSetCertificatePathInvalidData($input) { $this->expectException(InvalidArgument::class); $this->expectExceptionMessage('Argument #1 ($path) must be of type string|Stringable|bool'); Requests::set_certificate_path($input); } /** * Data Provider. * * @return array */ public function dataSetCertificatePathInvalidData() { return [ 'null' => [null], 'non-stringable object' => [new stdClass('value')], ]; } /** * Tests flattening of data arrays. * * @dataProvider dataFlattenValidData * * @covers \WpOrg\Requests\Requests::flatten * * @param mixed $input Valid input. * * @return void */ public function testFlattenValidData($input) { $expected = [ 0 => 'key1: value1', 1 => 'key2: value2', ]; $this->assertSame($expected, Requests::flatten($input)); } /** * Data Provider. * * @return array */ public function dataFlattenValidData() { $to_flatten = ['key1' => 'value1', 'key2' => 'value2']; return [ 'array' => [$to_flatten], 'iterable object' => [new ArrayIterator($to_flatten)], ]; } /** * Tests receiving an exception when an invalid input type is passed as `$dictionary` to the flatten() method. * * @dataProvider dataFlattenInvalidData * * @covers \WpOrg\Requests\Requests::flatten * * @param mixed $input Invalid input. * * @return void */ public function testFlattenInvalidData($input) { $this->expectException(InvalidArgument::class); $this->expectExceptionMessage('Argument #1 ($dictionary) must be of type iterable'); Requests::flatten($input); } /** * Data Provider. * * @return array */ public function dataFlattenInvalidData() { return [ 'null' => [null], 'array accessible object not iterable' => [new ArrayAccessibleObject([1, 2, 3])], ]; } }