]> git.mxchange.org Git - friendica.git/commitdiff
Extend test capability for HTTP Requests
authorPhilipp <admin@philipp.info>
Tue, 24 Aug 2021 22:13:50 +0000 (00:13 +0200)
committerPhilipp <admin@philipp.info>
Wed, 25 Aug 2021 12:22:43 +0000 (14:22 +0200)
src/Factory/HTTPClientFactory.php
tests/DiceHttpMockHandlerTrait.php [new file with mode: 0644]
tests/DiceTestTrait.php [deleted file]
tests/src/Network/ProbeTest.php
tests/src/Util/ImagesTest.php

index c1cb47541407d9bb32bc95990a444e61697b39e2..040ad75141b37781ec88cd90b1b93ad88cd3c1f0 100644 (file)
@@ -9,6 +9,7 @@ use Friendica\Network\HTTPClient;
 use Friendica\Network\IHTTPClient;
 use Friendica\Util\Profiler;
 use GuzzleHttp\Client;
+use GuzzleHttp\HandlerStack;
 use GuzzleHttp\RequestOptions;
 use mattwright\URLResolver;
 use Psr\Http\Message\RequestInterface;
@@ -33,7 +34,14 @@ class HTTPClientFactory extends BaseFactory
                $this->baseUrl  = $baseUrl;
        }
 
-       public function createClient(): IHTTPClient
+       /**
+        * Creates a IHTTPClient for communications with HTTP endpoints
+        *
+        * @param HandlerStack|null $handlerStack (optional) A handler replacement (just usefull at test environments)
+        *
+        * @return IHTTPClient
+        */
+       public function createClient(HandlerStack $handlerStack = null): IHTTPClient
        {
                $proxy = $this->config->get('system', 'proxy');
 
@@ -84,6 +92,7 @@ class HTTPClientFactory extends BaseFactory
                        RequestOptions::HEADERS => [
                                'User-Agent' => $userAgent,
                        ],
+                       'handler' => $handlerStack ?? HandlerStack::create(),
                ]);
 
                $resolver = new URLResolver();
diff --git a/tests/DiceHttpMockHandlerTrait.php b/tests/DiceHttpMockHandlerTrait.php
new file mode 100644 (file)
index 0000000..969b76b
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Test;
+
+use Dice\Dice;
+use Friendica\DI;
+use Friendica\Factory\HTTPClientFactory;
+use Friendica\Network\IHTTPClient;
+use GuzzleHttp\HandlerStack;
+
+/**
+ * This class injects a mockable handler into the IHTTPClient dependency per Dice
+ */
+trait DiceHttpMockHandlerTrait
+{
+       /**
+        * Handler for mocking requests anywhere for testing purpose
+        *
+        * @var HandlerStack
+        */
+       protected $httpRequestHandler;
+
+       protected function setupHttpMockHandler(): void
+       {
+               if (!empty($this->httpRequestHandler) && $this->httpRequestHandler instanceof HandlerStack) {
+                       return;
+               }
+
+               $this->httpRequestHandler = HandlerStack::create();
+
+               $dice = DI::getDice();
+               // addRule() clones the current instance and returns a new one, so no concurrency problems :-)
+               $newDice = $dice->addRule(IHTTPClient::class, [
+                       'instanceOf' => HTTPClientFactory::class,
+                       'call'       => [
+                               ['createClient', [$this->httpRequestHandler], Dice::CHAIN_CALL],
+                       ],
+               ]);
+
+               DI::init($newDice);
+       }
+
+       protected function tearDown(): void
+       {
+               \Mockery::close();
+
+               parent::tearDown();
+       }
+}
diff --git a/tests/DiceTestTrait.php b/tests/DiceTestTrait.php
deleted file mode 100644 (file)
index 2426c20..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Test;
-
-use Friendica\DI;
-use Friendica\Network\HTTPClient;
-use Friendica\Network\IHTTPClient;
-use GuzzleHttp\Client;
-use GuzzleHttp\HandlerStack;
-use mattwright\URLResolver;
-
-/**
- * This class mocks some DICE dependencies because they're not direct usable for test environments
- * (Like fetching data from external endpoints)
- */
-trait DiceTestTrait
-{
-       /**
-        * Handler for mocking requests anywhere for testing purpose
-        *
-        * @var HandlerStack
-        */
-       protected static $httpRequestHandler;
-
-       protected static function setUpDice(): void
-       {
-               if (!empty(self::$httpRequestHandler) && self::$httpRequestHandler instanceof HandlerStack) {
-                       return;
-               }
-
-               self::$httpRequestHandler = HandlerStack::create();
-
-               $client = new Client(['handler' => self::$httpRequestHandler]);
-
-               $resolver = \Mockery::mock(URLResolver::class);
-
-               $httpClient = new HTTPClient(DI::logger(), DI::profiler(), $client, $resolver);
-
-               $dice    = DI::getDice();
-               $newDice = \Mockery::mock($dice)->makePartial();
-               $newDice->shouldReceive('create')->with(IHTTPClient::class)->andReturn($httpClient);
-               DI::init($newDice);
-       }
-
-       protected function tearDown() : void
-       {
-               \Mockery::close();
-
-               parent::tearDown();
-       }
-}
index 58711cb916f9c9442a2298e9b572955b1bfe0bc2..79c323adc202bbcd539078358d1ae8fe38c454d5 100644 (file)
@@ -3,10 +3,21 @@
 namespace Friendica\Test\src\Network;
 
 use Friendica\Network\Probe;
-use PHPUnit\Framework\TestCase;
+use Friendica\Test\DiceHttpMockHandlerTrait;
+use Friendica\Test\FixtureTest;
+use GuzzleHttp\Middleware;
 
-class ProbeTest extends TestCase
+class ProbeTest extends FixtureTest
 {
+       use DiceHttpMockHandlerTrait;
+
+       protected function setUp(): void
+       {
+               parent::setUp();
+
+               $this->setupHttpMockHandler();
+       }
+
        const TEMPLATENOBASE = '
 <!DOCTYPE html>
 <html lang="en-us">
@@ -105,4 +116,122 @@ class ProbeTest extends TestCase
                        }
                }
        }
+
+       public function dataUri()
+       {
+               return [
+                       '@-first' => [
+                               'uri'         => '@Artists4Future_Muenchen@climatejustice.global',
+                               'assertUri'   => 'Artists4Future_Muenchen@climatejustice.global',
+                               'assertInfos' => [
+                                       'name'         => 'Artists4Future München',
+                                       'nick'         => 'Artists4Future_Muenchen',
+                                       'url'          => 'https://climatejustice.global/users/Artists4Future_Muenchen',
+                                       'alias'        => 'https://climatejustice.global/@Artists4Future_Muenchen',
+                                       'photo'        => 'https://cdn.masto.host/climatejusticeglobal/accounts/avatars/000/021/220/original/05ee9e827a5b47fc.jpg',
+                                       'header'       => 'https://cdn.masto.host/climatejusticeglobal/accounts/headers/000/021/220/original/9b98b75cf696cd11.jpg',
+                                       'account-type' => 0,
+                                       'about'        => 'Wir sind Künstler oder einfach gerne kreativ tätig und setzen uns unabhängig von politischen Parteien für den Klimaschutz ein. Die Bedingungen zu schaffen, die die [url=https://climatejustice.global/tags/Klimakrise]#Klimakrise[/url] verhindern/eindämmen (gemäß den Forderungen der [url=https://climatejustice.global/tags/Fridays4Future]#Fridays4Future[/url]) ist Aufgabe der Politik, muss aber gesamtgesellschaftlich getragen werden. Mit unseren künstlerischen Aktionen wollen wir einen anderen Zugang anbieten für wissenschaftlich rationale Argumente, speziell zur Erderwärmung und ihre Konsequenzen.',
+                                       'hide'         => 0,
+                                       'batch'        => 'https://climatejustice.global/inbox',
+                                       'notify'       => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox',
+                                       'poll'         => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox',
+                                       'subscribe'    => 'https://climatejustice.global/authorize_interaction?uri={uri}',
+                                       'following'    => 'https://climatejustice.global/users/Artists4Future_Muenchen/following',
+                                       'followers'    => 'https://climatejustice.global/users/Artists4Future_Muenchen/followers',
+                                       'inbox'        => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox',
+                                       'outbox'       => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox',
+                                       'sharedinbox'  => 'https://climatejustice.global/inbox',
+                                       'priority'     => 0,
+                                       'network'      => 'apub',
+                                       'pubkey'       => '-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6pYKPuDKb+rmBB869uPV
+uLYFPosGxMUfenWqfWmFKzEqJ87rAft0IQDAL6dCoYE55ov/lEDNROhasTZLirZf
+M5b7/1JmwMrAfEiaciuYqDWT3/yDpnekOIdzP5iSClg4zt7e6HRFuClqo4+b6hIE
+DTMV4ksItvq/92MIu62pZ2SZr5ADPPZ/914lJ86hIH5BanbE8ZFzDS9vJA7V74rt
+Vvkr5c/OiUyuODNYApSl87Ez8cuj8Edt89YWkDCajQn3EkmXGeJY/VRjEDfcyk6r
+AvdUa0ArjXud3y3NkakVFZ0d7tmB20Vn9s/CfYHU8FXzbI1kFkov2BX899VVP5Ay
+xQIDAQAB
+-----END PUBLIC KEY-----',
+                                       'manually-approve' => 0,
+                                       'baseurl'          => 'https://climatejustice.global',
+                               ]
+                       ]
+               ];
+       }
+
+       /**
+        * @dataProvider dataUri
+        */
+       public function testCleanUri(string $uri, string $assertUri, array $assertInfos)
+       {
+               self::markTestIncomplete('hard work due mocking 19 different http-requests');
+
+               /**
+                * Requests:
+                *
+                * GET : https://climatejustice.global/.well-known/webfinger?resource=acct:Artists4Future_Muenchen%40climatejustice.global
+                * 200
+                * GET : http://localhost/.well-known/nodeinfo
+                * 200
+                * GET : http://localhost/statistics.json
+                * 404
+                * GET : http://localhost
+                * 200
+                * GET : http://localhost/friendica/json
+                * 404
+                * GET : http://localhost/friendika/json
+                * 404
+                * GET : http://localhost/poco
+                * 403
+                * GET : http://localhost/api/v1/directory?limit=1
+                * 200
+                * GET : http://localhost/.well-known/x-social-relay
+                * 200
+                * GET : http://localhost/friendica
+                * 404
+                * GET : https://climatejustice.global/users/Artists4Future_Muenchen
+                * 200
+                * GET : https://climatejustice.global/users/Artists4Future_Muenchen/following
+                * 200
+                * GET : https://climatejustice.global/users/Artists4Future_Muenchen/followers
+                * 200
+                * GET : https://climatejustice.global/users/Artists4Future_Muenchen/outbox
+                * 200
+                * GET : https://climatejustice.global/.well-known/nodeinfo
+                * 200
+                * GET : https://climatejustice.global/nodeinfo/2.0
+                * 200
+                * GET : https://climatejustice.global/poco
+                * 404
+                * GET : https://climatejustice.global/api/v1/directory?limit=1
+                * 200
+                * GET : https://climatejustice.global/.well-known/webfinger?resource=acct%3AArtists4Future_Muenchen%40climatejustice.global
+                * 200
+                *
+                */
+
+               $container = [];
+               $history   = Middleware::history($container);
+
+               $this->httpRequestHandler->push($history);
+
+               $cleaned = Probe::cleanURI($uri);
+               self::assertEquals($assertUri, $cleaned);
+               self::assertArraySubset($assertInfos, Probe::uri($cleaned, '', 0));
+
+
+               // Iterate over the requests and responses
+               foreach ($container as $transaction) {
+                       echo $transaction['request']->getMethod() . " : " . $transaction['request']->getUri() . PHP_EOL;
+                       //> GET, HEAD
+                       if ($transaction['response']) {
+                               echo $transaction['response']->getStatusCode() . PHP_EOL;
+                       //> 200, 200
+                       } elseif ($transaction['error']) {
+                               echo $transaction['error'];
+                               //> exception
+                       }
+               }
+       }
 }
index a7cc682f9853ff2623f79095e6f7274160ac0957..ddadf9547f0be1f5c761221e885aba78285b8bc6 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace Friendica\Test\src\Util;
 
-use Friendica\Test\DiceTestTrait;
+use Friendica\Test\DiceHttpMockHandlerTrait;
 use Friendica\Test\MockedTest;
 use Friendica\Util\Images;
 use GuzzleHttp\Handler\MockHandler;
@@ -10,13 +10,13 @@ use GuzzleHttp\Psr7\Response;
 
 class ImagesTest extends MockedTest
 {
-       use DiceTestTrait;
+       use DiceHttpMockHandlerTrait;
 
-       public static function setUpBeforeClass(): void
+       protected function setUp(): void
        {
-               parent::setUpBeforeClass();
+               parent::setUp();
 
-               self::setUpDice();
+               $this->setupHttpMockHandler();
        }
 
        public function dataImages()
@@ -56,13 +56,13 @@ class ImagesTest extends MockedTest
        }
 
        /**
-        * Test the Images::getInfoFromURL() method
+        * Test the Images::getInfoFromURL() method (only remote images, not local/relative!)
         *
         * @dataProvider dataImages
         */
-       public function testGetInfoFromURL(string $url, array $headers, string $data, array $assertion)
+       public function testGetInfoFromRemotURL(string $url, array $headers, string $data, array $assertion)
        {
-               self::$httpRequestHandler->setHandler(new MockHandler([
+               $this->httpRequestHandler->setHandler(new MockHandler([
                        new Response(200, $headers, $data),
                ]));