Browse Source

basePath configuration added to the client
tests updated to use basePath prepended and appended forward slash characters are stripped and re-added when building a url
Updated tests for exceptions and required variables

Eugene Ritter 5 years ago
parent
commit
80820af6ea
2 changed files with 61 additions and 14 deletions
  1. 12 2
      src/Http/Client.php
  2. 49 12
      tests/TestCase/Http/ClientTest.php

+ 12 - 2
src/Http/Client.php

@@ -114,6 +114,7 @@ class Client implements ClientInterface
         'host' => null,
         'port' => null,
         'scheme' => 'http',
+        'basePath' => '',
         'timeout' => 30,
         'ssl_verify_peer' => true,
         'ssl_verify_peer_name' => true,
@@ -150,6 +151,7 @@ class Client implements ClientInterface
      * - host - The hostname to do requests on.
      * - port - The port to use.
      * - scheme - The default scheme/protocol to use. Defaults to http.
+     * - basePath - A path to append to the domain to use. (/api/v1/)
      * - timeout - The timeout in seconds. Defaults to 30
      * - ssl_verify_peer - Whether or not SSL certificates should be validated.
      *   Defaults to true.
@@ -244,12 +246,18 @@ class Client implements ClientInterface
             throw new InvalidArgumentException('String ' . $url . ' did not parse');
         }
 
-        $config = array_intersect_key($parts, ['scheme' => '', 'port' => '', 'host' => '']);
+        $config = array_intersect_key($parts, ['scheme' => '', 'port' => '', 'host' => '', 'path' => '']);
+        $config = array_merge(['scheme' => '', 'host' => ''], $config);
 
-        if (!isset($config['scheme']) || !isset($config['host'])) {
+        if (empty($config['scheme']) || empty($config['host'])) {
             throw new InvalidArgumentException('The URL was parsed but did not contain a scheme or host');
         }
 
+        if (isset($config['path'])) {
+            $config['basePath'] = $config['path'];
+            unset($config['path']);
+        }
+
         return new static($config);
     }
 
@@ -519,6 +527,7 @@ class Client implements ClientInterface
             'host' => null,
             'port' => null,
             'scheme' => 'http',
+            'basePath' => '',
             'protocolRelative' => false,
         ];
         $options += $defaults;
@@ -538,6 +547,7 @@ class Client implements ClientInterface
         if ($options['port'] && (int)$options['port'] !== $defaultPorts[$options['scheme']]) {
             $out .= ':' . $options['port'];
         }
+        $out .= '/' . trim($options['basePath'], '/');
         $out .= '/' . ltrim($url, '/');
 
         return $out;

+ 49 - 12
tests/TestCase/Http/ClientTest.php

@@ -39,6 +39,7 @@ class ClientTest extends TestCase
         $config = [
             'scheme' => 'http',
             'host' => 'example.org',
+            'basePath' => '/api/v1',
         ];
         $http = new Client($config);
         $result = $http->getConfig();
@@ -113,6 +114,27 @@ class ClientTest extends TestCase
                 'HTTPS',
             ],
             [
+                'https://example.com/api/v1/foo/test.html',
+                '/foo/test.html',
+                [],
+                ['host' => 'example.com', 'scheme' => 'https', 'basePath' => '/api/v1'],
+                'Base path included',
+            ],
+            [
+                'https://example.com/api/v1/foo/test.html',
+                '/foo/test.html',
+                [],
+                ['host' => 'example.com', 'scheme' => 'https', 'basePath' => '/api/v1/'],
+                'Base path with trailing forward slash',
+            ],
+            [
+                'https://example.com/api/v1/foo/test.html',
+                '/foo/test.html',
+                [],
+                ['host' => 'example.com', 'scheme' => 'https', 'basePath' => 'api/v1/'],
+                'Base path with no prepended forward slash',
+            ],
+            [
                 'http://example.com:8080/test.html',
                 '/test.html',
                 [],
@@ -918,6 +940,15 @@ class ClientTest extends TestCase
     }
 
     /**
+     * basePath is set when passed to client in string
+     */
+    public function testCreateFromUrlSetsBasePath()
+    {
+        $client = Client::createFromUrl('https://example.co/api/v1');
+        $this->assertSame('/api/v1', $client->getConfig('basePath'));
+    }
+
+    /**
      * Test exception is thrown when URL cannot be parsed
      */
     public function testCreateFromUrlThrowsInvalidExceptionWhenUrlCannotBeParsed()
@@ -954,27 +985,33 @@ class ClientTest extends TestCase
     public function testCreateFromUrlThrowsInvalidArgumentExceptionWhenNoDomainProvided()
     {
         $this->expectException(InvalidArgumentException::class);
-        Client::createFromUrl('https://');
+        Client::createFromUrl('/api/v1');
         $message = $this->getExpectedExceptionMessage();
         $this->assertSame('The URL was parsed but did not contain a scheme or host', $message);
     }
 
     /**
      * Test that the passed parsed URL parts won't override other constructor defaults
+     * or add undefined configuration
      */
-    public function testCreateFromUrlOnlySetSchemePortHost()
+    public function testCreateFromUrlOnlySetSchemePortHostBasePath()
     {
         $client = Client::createFromUrl('http://example.co:80/some/uri/?foo=bar');
         $config = $client->getConfig();
-        $this->assertSame('http', $config['scheme']);
-        $this->assertSame('example.co', $config['host']);
-        $this->assertSame(80, $config['port']);
-        $this->assertSame(null, $config['adapter']);
-        $this->assertSame(30, $config['timeout']);
-        $this->assertSame(true, $config['ssl_verify_peer']);
-        $this->assertSame(true, $config['ssl_verify_peer_name']);
-        $this->assertSame(true, $config['ssl_verify_host']);
-        $this->assertSame(false, $config['redirect']);
-        $this->assertSame('1.1', $config['protocolVersion']);
+        $expected = [
+            'adapter' => null,
+            'host' => 'example.co',
+            'port' => 80,
+            'scheme' => 'http',
+            'basePath' => '/some/uri',
+            'timeout' => 30,
+            'ssl_verify_peer' => true,
+            'ssl_verify_peer_name' => true,
+            'ssl_verify_depth' => 5,
+            'ssl_verify_host' => true,
+            'redirect' => false,
+            'protocolVersion' => '1.1',
+        ];
+        $this->assertSame($expected, $config);
     }
 }