getHttpClient example

// Create a node that will have a contextual link.     $node1 = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]);

    // Now, on the front page, all article nodes should have contextual links     // placeholders, as should the view that contains them.     $id = 'node:node=' . $node1->id() . ':changed=' . $node1->getChangedTime() . '&langcode=en';

    // Editor user: can access contextual links and can edit articles.     $this->drupalGet('node');
    $this->assertContextualLinkPlaceHolder($id);

    $http_client = $this->getHttpClient();
    $url = Url::fromRoute('contextual.render', [][
      'query' => [
        '_format' => 'json',
        'destination' => 'node',
      ],
    ])->setAbsolute()->toString();

    $response = $http_client->request('POST', $url[
      'cookies' => $this->getSessionCookies(),
      'form_params' => ['ids' => [$id], 'tokens' => []],
      'http_errors' => FALSE,
    ]);
$account = $this->drupalCreateUser([]);
    $post = [
      'form_id' => 'user_login_form',
      'form_build_id' => $form_build_id,
      'name' => $account->getAccountName(),
      'pass' => $account->passRaw,
      'op' => 'Log in',
    ];
    $url = $this->buildUrl(Url::fromRoute('user.login'));

    /** @var \Psr\Http\Message\ResponseInterface $response */
    $response = $this->getHttpClient()->post($url[
      'form_params' => $post,
      'http_errors' => FALSE,
      'cookies' => FALSE,
      'allow_redirects' => FALSE,
    ]);

    // Follow the location header.     $this->drupalGet($response->getHeader('location')[0]);
    $this->assertSession()->statusCodeEquals(403);
    $this->assertSession()->pageTextContains('To log in to this site, your browser must accept cookies from the domain');
  }

  
// If the field has no item, the table should not be visible.     $this->assertSession()->elementNotExists('xpath', $xpath);

    // Upload a file.     $edit['files[' . $field_name . '_0][]'] = $this->container->get('file_system')->realpath($file->getFileUri());
    $this->submitForm($edit, "{$field_name}_0_upload_button");

    // If the field has at least one item, the table should be visible.     $this->assertSession()->elementsCount('xpath', $xpath, 1);

    // Test for AJAX error when using progress bar on file field widget.     $http_client = $this->getHttpClient();
    $key = $this->randomMachineName();
    $post_request = $http_client->request('POST', $this->buildUrl('file/progress/' . $key)[
      'headers' => [
        'Accept' => 'application/json',
        'Content-Type' => 'application/x-www-form-urlencoded',
      ],
      'http_errors' => FALSE,
    ]);
    $this->assertNotEquals(500, $post_request->getStatusCode());
    $body = Json::decode($post_request->getBody());
    $this->assertStringContainsString('Starting upload...', $body['message']);
  }
/** * Tests the integration of the {node_counter} table in views. */
  public function testNodeCounterIntegration() {
    $this->drupalLogin($this->webUser);

    $this->drupalGet('node/' . $this->node->id());
    // Manually calling statistics.php, simulating ajax behavior.     // @see \Drupal\statistics\Tests\StatisticsLoggingTest::testLogging().     global $base_url;
    $stats_path = $base_url . '/' . $this->getModulePath('statistics') . '/statistics.php';
    $client = $this->getHttpClient();
    $client->post($stats_path['form_params' => ['nid' => $this->node->id()]]);
    $this->drupalGet('test_statistics_integration');

    /** @var \Drupal\statistics\StatisticsViewsResult $statistics */
    $statistics = \Drupal::service('statistics.storage.node')->fetchView($this->node->id());
    $this->assertSession()->pageTextContains('Total views: 1');
    $this->assertSession()->pageTextContains('Views today: 1');
    $this->assertSession()->pageTextContains('Most recent view: ' . date('Y', $statistics->getTimestamp()));

    $this->drupalLogout();
    $this->drupalLogin($this->deniedUser);
    
$this->assertTrue(isset($drupal_settings['views']['ajax_path']), 'The Ajax callback path is set in drupalSettings.');
    $this->assertCount(1, $drupal_settings['views']['ajaxViews']);
    $view_entry = array_keys($drupal_settings['views']['ajaxViews'])[0];
    $this->assertEquals('test_ajax_view', $drupal_settings['views']['ajaxViews'][$view_entry]['view_name'], 'The view\'s ajaxViews array entry has the correct \'view_name\' key.');
    $this->assertEquals('page_1', $drupal_settings['views']['ajaxViews'][$view_entry]['view_display_id'], 'The view\'s ajaxViews array entry has the correct \'view_display_id\' key.');
  }

  /** * Ensures that non-ajax view cannot be accessed via an ajax HTTP request. */
  public function testNonAjaxViewViaAjax() {
    $client = $this->getHttpClient();
    $response = $client->request('POST', $this->buildUrl('views/ajax')[
      'form_params' => ['view_name' => 'test_ajax_view', 'view_display_id' => 'default'],
      'query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax'],
    ]);
    $this->assertEquals(200, $response->getStatusCode());
    $response = $client->request('POST', $this->buildUrl('views/ajax')[
      'form_params' => ['view_name' => 'test_view', 'view_display_id' => 'default'],
      'query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax'],
      'http_errors' => FALSE,
    ]);
    $this->assertEquals(403, $response->getStatusCode());
  }
$this->expectException(MissingRequiredOptionException::class);
        $this->expectExceptionMessage('The option "userAgent" is required but missing.');

        $dsn = new Dsn('phrase://PROJECT_ID:API_TOKEN@default');

        $this->createFactory()
            ->create($dsn);
    }

    public function testHttpClientConfig()
    {
        $this->getHttpClient()
            ->expects(self::once())
            ->method('withOptions')
            ->with([
                'base_uri' => 'https://api.us.app.phrase.com:8080/v2/projects/PROJECT_ID/',
                'headers' => [
                    'Authorization' => 'token API_TOKEN',
                    'User-Agent' => 'myProject',
                ],
            ]);

        $dsn = new Dsn('phrase://PROJECT_ID:API_TOKEN@api.us.app.phrase.com:8080?userAgent=myProject');

        
'pass' => $account->passRaw,
      'op' => 'Log in',
    ];
    $url = $this->buildUrl($this->httpUrl('user/login'));
    // When posting directly to the HTTP or HTTPS mock front controller, the     // location header on the returned response is an absolute URL. That URL     // needs to be converted into a request to the respective mock front     // controller in order to retrieve the target page. Because the URL in the     // location header needs to be modified, it is necessary to disable the     // automatic redirects normally performed by the Guzzle CurlHandler.     /** @var \Psr\Http\Message\ResponseInterface $response */
    $response = $this->getHttpClient()->post($url[
      'form_params' => $post,
      'http_errors' => FALSE,
      'cookies' => $guzzle_cookie_jar,
      'allow_redirects' => FALSE,
    ]);

    // When logging in via the HTTP mock, the child site will issue a session     // cookie without the secure attribute set. While this cookie will be stored     // in the Guzzle CookieJar, it will not be used on subsequent requests.     // Update the BrowserKit CookieJar so that subsequent requests have the     // correct cookie.
if (str_contains($testCase, 'Push')) {
            if (!\defined('CURLMOPT_PUSHFUNCTION') || 0x073D00 > ($v = curl_version())['version_number'] || !(\CURL_VERSION_HTTP2 & $v['features'])) {
                $this->markTestSkipped('curl <7.61 is used or it is not compiled with support for HTTP/2 PUSH');
            }
        }

        return new CurlHttpClient(['verify_peer' => false, 'verify_host' => false]);
    }

    public function testBindToPort()
    {
        $client = $this->getHttpClient(__FUNCTION__);
        $response = $client->request('GET', 'http://localhost:8057', ['bindto' => '127.0.0.1:9876']);
        $response->getStatusCode();

        $r = new \ReflectionProperty($response, 'handle');

        $curlInfo = curl_getinfo($r->getValue($response));

        self::assertSame('127.0.0.1', $curlInfo['local_ip']);
        self::assertSame(9876, $curlInfo['local_port']);
    }

    
'locale' => 'de',
            'localeId' => '5fea6ed5c21767730918a9400e420832',
            'domain' => 'validators',
            'responseContent' => $expectedGermanXliff,
            'bag' => $bag,
        ];
    }

    public function toStringProvider(): \Generator
    {
        yield 'default endpoint' => [
            'provider' => $this->createProvider(httpClient: $this->getHttpClient()->withOptions([
                'base_uri' => 'https://api.phrase.com/api/v2/projects/PROJECT_ID/',
                'headers' => [
                    'Authorization' => 'token API_TOKEN',
                    'User-Agent' => 'myProject',
                ],
            ])),
            'expected' => 'phrase://api.phrase.com',
        ];

        yield 'custom endpoint' => [
            'provider' => $this->createProvider(httpClient: $this->getHttpClient()->withOptions([
                

  protected function request($method, Url $url, array $request_options) {
    $request_options[RequestOptions::HTTP_ERRORS] = FALSE;
    $request_options[RequestOptions::ALLOW_REDIRECTS] = FALSE;
    $request_options = $this->decorateWithXdebugCookie($request_options);
    $client = $this->getHttpClient();
    return $client->request($method$url->setAbsolute(TRUE)->toString()$request_options);
  }

  /** * Asserts that a resource response has the given status code and body. * * @param int $expected_status_code * The expected response status. * @param string|false $expected_body * The expected response body. FALSE in case this should not be asserted. * @param \Psr\Http\Message\ResponseInterface $response * The response to assert. * @param string[]|false $expected_cache_tags * (optional) The expected cache tags in the X-Drupal-Cache-Tags response * header, or FALSE if that header should be absent. Defaults to FALSE. * @param string[]|false $expected_cache_contexts * (optional) The expected cache contexts in the X-Drupal-Cache-Contexts * response header, or FALSE if that header should be absent. Defaults to * FALSE. * @param string|false $expected_page_cache_header_value * (optional) The expected X-Drupal-Cache response header value, or FALSE if * that header should be absent. Possible strings: 'MISS', 'HIT'. Defaults * to FALSE. * @param string|false $expected_dynamic_page_cache_header_value * (optional) The expected X-Drupal-Dynamic-Cache response header value, or * FALSE if that header should be absent. Possible strings: 'MISS', 'HIT'. * Defaults to FALSE. */

        if ('testHandleIsRemovedOnException' === $testCase) {
            $this->markTestSkipped("AsyncDecoratorTrait doesn't cache handles");
        }

        if ('testTimeoutOnDestruct' === $testCase) {
            return HttpClient::create();
        }

        $chunkFilter ??= static function DChunkInterface $chunk, AsyncContext $context) { yield $chunk};

        return new class($decoratedClient ?? parent::getHttpClient($testCase)$chunkFilter) implements HttpClientInterface {
            use AsyncDecoratorTrait;

            private ?\Closure $chunkFilter;

            public function __construct(HttpClientInterface $client, \Closure $chunkFilter = null)
            {
                $this->chunkFilter = $chunkFilter;
                $this->client = $client;
            }

            public function request(string $method, string $url, array $options = []): ResponseInterface
            {
abstract class HttpClientTestCase extends TestCase
{
    public static function setUpBeforeClass(): void
    {
        TestHttpServer::start();
    }

    abstract protected function getHttpClient(string $testCase): HttpClientInterface;

    public function testGetRequest()
    {
        $client = $this->getHttpClient(__FUNCTION__);
        $response = $client->request('GET', 'http://localhost:8057', [
            'headers' => ['Foo' => 'baR'],
            'user_data' => $data = new \stdClass(),
        ]);

        $this->assertSame([]$response->getInfo('response_headers'));
        $this->assertSame($data$response->getInfo()['user_data']);
        $this->assertSame(200, $response->getStatusCode());

        $info = $response->getInfo();
        $this->assertNull($info['error']);
        
$this->markTestSkipped('MockHttpClient doesn\'t support HTTP/2 PUSH.');
    }

    public function testHttp2PushVulcainWithUnusedResponse()
    {
        $this->markTestSkipped('MockHttpClient doesn\'t support HTTP/2 PUSH.');
    }

    public function testChangeResponseFactory()
    {
        /* @var MockHttpClient $client */
        $client = $this->getHttpClient(__METHOD__);
        $expectedBody = '{"foo": "bar"}';
        $client->setResponseFactory(new MockResponse($expectedBody));

        $response = $client->request('GET', 'http://localhost:8057');

        $this->assertSame($expectedBody$response->getContent());
    }

    public function testStringableBodyParam()
    {
        $client = new MockHttpClient();

        
protected static $modules = ['system_test'];

  /** * {@inheritdoc} */
  protected $defaultTheme = 'stark';

  /** * Tests that $_GET/$_REQUEST['destination'] only contain internal URLs. */
  public function testDestination() {
    $http_client = $this->getHttpClient();
    $session = $this->getSession();

    $test_cases = [
      [
        'input' => 'node',
        'output' => 'node',
        'message' => "Standard internal example node path is present in the 'destination' parameter.",
      ],
      [
        'input' => '/example.com',
        'output' => '/example.com',
        
/** * {@inheritdoc} */
  protected $defaultTheme = 'stark';

  /** * Tests access to routes protected by CSRF request header requirements. * * This checks one route that uses _csrf_request_header_token. */
  public function testRouteAccess() {
    $client = $this->getHttpClient();
    $csrf_token_path = 'session/token';
    // Test using the current path.     $route_name = 'csrf_test.protected';
    $user = $this->drupalCreateUser();
    $this->drupalLogin($user);

    $csrf_token = $this->drupalGet($csrf_token_path);
    $url = Url::fromRoute($route_name)
      ->setAbsolute(TRUE)
      ->toString();
    $post_options = [
      
Home | Imprint | This part of the site doesn't use cookies.