8000 Add HttpClientAssertionsTrait which provide shortcut to assert HTTP c… · symfony/symfony@1d5c59b · GitHub
[go: up one dir, main page]

Skip to content

Commit 1d5c59b

Browse files
committed
Add HttpClientAssertionsTrait which provide shortcut to assert HTTP call was triggered
1 parent 52a9292 commit 1d5c59b

File tree

10 files changed

+214
-0
lines changed

10 files changed

+214
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Test;
13+
14+
/*
15+
* @author Mathieu Santostefano <msantostefano@protonmail.com>
16+
*/
17+
18+
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
19+
use Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector;
20+
21+
trait HttpClientAssertionsTrait
22+
{
23+
public static function assertHttpClientHasBeenCalledForUrl(KernelBrowser $client, string $httpClientId, string $expectedUrl, string $expectedMethod = 'GET', string|array $expectedBody = null): void
24+
{
25+
if (($profile = $client->getProfile()) === false) {
26+
static::fail('The Profiler must be enabled for the current request. Please ensure you have called $client->enableProfiler() before making the request.');
27+
}
28+
29+
/** @var HttpClientDataCollector $httpClientDataCollector */
30+
$httpClientDataCollector = $profile->getCollector('http_client');
31+
$expectedUrlHasBeenFound = false;
32+
33+
foreach ($httpClientDataCollector->getClients()[$httpClientId]['traces'] as $trace) {
34+
if ($expectedUrl === $trace['info']['url'] && $expectedMethod === $trace['method']) {
35+
if ($expectedBody !== null) {
36+
$actualBody = is_string($trace['options']['body']) ? $trace['options']['body'] : $trace['options']['body']->getValue(true);
37+
38+
if ($expectedBody === $actualBody) {
39+
$expectedUrlHasBeenFound = true;
40+
break;
41+
}
42+
43+
continue;
44+
}
45+
46+
$expectedUrlHasBeenFound = true;
47+
break;
48+
}
49+
}
50+
51+
self::assertTrue($expectedUrlHasBeenFound, 'The expected URL has not called: "'.$expectedMethod.'" - "'.$expectedUrl.'"');
52+
}
53+
54+
public function assertHttpClientHasNotBeenCalledForUrl(KernelBrowser $client, string $httpClientId, string $unexpectedUrl, string $expectedMethod = 'GET'): void
55+
{
56+
if (($profile = $client->getProfile()) === false) {
57+
static::fail('The Profiler must be enabled for the current request. Please ensure you have called $client->enableProfiler() before making the request.');
58+
}
59+
60+
/** @var HttpClientDataCollector $httpClientDataCollector */
61+
$httpClientDataCollector = $profile->getCollector('http_client');
62+
$unexpectedUrlHasBeenFound = false;
63+
64+
foreach ($httpClientDataCollector->getClients()[$httpClientId]['traces'] as $trace) {
65+
if ($unexpectedUrl === $trace['info']['url'] && $expectedMethod === $trace['method']) {
66+
$unexpectedUrlHasBeenFound = true;
67+
break;
68+
}
69+
}
70+
71+
self::assertFalse($unexpectedUrlHasBeenFound, 'The unexpected URL has been called: "'.$expectedMethod.'" - "'.$unexpectedUrl.'"');
72+
}
73+
74+
public static function assertHttpClientCountRequests(KernelBrowser $client, string $httpClientId, int $count): void
75+
{
76+
if (($profile = $client->getProfile()) === false) {
77+
static::fail('The Profiler must be enabled for the current request. Please ensure you have called $client->enableProfiler() before making the request.');
78+
}
79+
80+
/** @var HttpClientDataCollector $httpClientDataCollector */
81+
$httpClientDataCollector = $profile->getCollector('http_client');
82+
83+
self::assertCount($count, $httpClientDataCollector->getClients()[$httpClientId]['traces']);
84+
}
85+
}

src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ trait WebTestAssertionsTrait
1515
{
1616
use BrowserKitAssertionsTrait;
1717
use DomCrawlerAssertionsTrait;
18+
use HttpClientAssertionsTrait;
1819
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller;
13+
14+
use Symfony\Component\HttpFoundation\Response;
15+
use Symfony\Contracts\HttpClient\HttpClientInterface;
16+
17+
class HttpClientController
18+
{
19+
public function index(HttpClientInterface $symfonyHttpClient): Response
20+
{
21+
$symfonyHttpClient->request('GET', '/');
22+
$symfonyHttpClient->request('POST', '/', ['body' => 'foo']);
23+
$symfonyHttpClient->request('POST', '/', ['body' => ['foo' => 'bar']]);
24+
$symfonyHttpClient->request('POST', '/', ['json' => ['foo' => 'bar']]);
25+
$symfonyHttpClient->request('GET', '/doc/current/index.html');
26+
27+
return new Response();
28+
}
29+
}

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ send_email:
6161
path: /send_email
6262
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\EmailController::indexAction }
6363

64+
http_client_call:
65+
path: /http_client_call
66+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\HttpClientController::index }
67+
6468
uid:
6569
resource: "../../Controller/UidController.php"
6670
type: "annotation"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Tests;
13+
14+
use Symfony\Component\HttpClient\Response\MockResponse;
15+
use Symfony\Contracts\HttpClient\ResponseInterface;
16+
17+
class MockClientCallback
18+
{
19+
public function __invoke(string $method, string $url, array $options = []): ResponseInterface
20+
{
21+
return new MockResponse('foo');
22+
}
23+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
13+
14+
class HttpClientTest extends AbstractWebTestCase
15+
{
16+
public function testHttpClientAssertions()
17+
{
18+
$client = $this->createClient(['test_case' => 'HttpClient', 'root_config' => 'config.yml', 'debug' => true]);
19+
$client->enableProfiler();
20+
$client->request('GET', '/http_client_call');
21+
22+
$this->assertHttpClientHasBeenCalledForUrl($client, 'symfony.http_client', 'https://symfony.com/');
23+
$this->assertHttpClientHasBeenCalledForUrl($client, 'symfony.http_client', 'https://symfony.com/', 'POST', 'foo');
24+
$this->assertHttpClientHasBeenCalledForUrl($client, 'symfony.http_client', 'https://symfony.com/', 'POST', ['foo' => 'bar']);
25+
$this->assertHttpClientHasBeenCalledForUrl($client, 'symfony.http_client', 'https://symfony.com/', 'POST', ['foo' => 'bar']);
26+
$this->assertHttpClientHasBeenCalledForUrl($client, 'symfony.http_client', 'https://symfony.com/doc/current/index.html');
27+
$this->assertHttpClientHasNotBeenCalledForUrl($client, 'symfony.http_client', 'https://laravel.com');
28+
29+
$this->assertHttpClientCountRequests($client, 'symfony.http_client', 5);
30+
}
31+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
13+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
14+
15+
return [
16+
new FrameworkBundle(),
17+
new TestBundle(),
18+
];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
imports:
2+
- { resource: ../config/default.yml }
3+
- { resource: services.yml }
4+
5+
framework:
6+
http_method_override: false
7+
profiler: ~
8+
http_client:
9+
mock_response_factory: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Tests\MockClientCallback
10+
scoped_clients:
11+
symfony.http_client:
12+
base_uri: 'https://symfony.com'
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
_emailtest_bundle:
2+
resource: '@TestBundle/Resources/config/routing.yml'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
_defaults:
3+
public: true
4+
5+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\HttpClientController:
6+
tags: ['controller.service_arguments']
7+
8+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Tests\MockClientCallback:
9+
class: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Tests\MockClientCallback

0 commit comments

Comments
 (0)
0