Unverified Commit 255ff3ed authored by Alex Pott's avatar Alex Pott
Browse files

task: #3582228 add $options and $headers parameters to HttpKernelUiHelperTrait::drupalGet()

By: joachim
By: catch
By: dww
By: mstrelan
By: smustgrave
By: alexpott
parent d4014a7d
Loading
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

namespace Drupal\KernelTests;

use Drupal\Core\Url;
use Drupal\Tests\HttpKernelUiHelperTrait;
use PHPUnit\Framework\Attributes\CoversTrait;
use PHPUnit\Framework\Attributes\Group;
@@ -44,6 +45,40 @@ public function testRequest(): void {
    $this->drupalGet('/system-test/main-content-handling');
    $this->assertEquals(Response::HTTP_OK, $this->getSession()->getStatusCode());
    $this->assertSession()->pageTextContains('Content to test main content fallback');

    // Test drupalGet() with Url options.
    $this->drupalGet('/system-test/set-header', [
      'query' => [
        'name' => 'meaning',
        'value' => '42',
      ],
    ]);
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('The following header was set: meaning: 42');

    // Test drupalGet() with a URL object.
    $url = Url::fromRoute('system_test.main_content_handling');
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Test drupalGet() with a URL object with options.
    $url = Url::fromRoute('system_test.set_header', [], [
      'query' => [
        'name' => 'meaning',
        'value' => '42',
      ],
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('The following header was set: meaning: 42');

    // Test that setting headers with drupalGet() works.
    $this->drupalGet('system-test/header', [], [
      'Test-Header' => 'header value',
    ]);
    // We can't use WebAssert::responseHeaderExists() because of how header
    // names are normalized by Mink and Symfony.
    $this->assertEquals('header value', $this->getSession()->getResponseHeader('Test-Header'));
  }

  /**
+56 −6
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
use Behat\Mink\Mink;
use Behat\Mink\Selector\SelectorsHandler;
use Behat\Mink\Session;
use Drupal\Core\Url;
use Symfony\Component\HttpKernel\HttpKernelBrowser;

/**
@@ -42,23 +43,44 @@ trait HttpKernelUiHelperTrait {
   *
   * Requests are sent to the HTTP kernel.
   *
   * @param string $path
   *   The Drupal path to load into Mink controlled browser. (Note that the
   *   Symfony browser's functionality of paths relative to the previous request
   *   is not available, because an initial '/' is assumed if not present.)
   * @param \Drupal\Core\Url|string $path
   *   The Drupal path to load into Mink controlled browser, as a string or a
   *   Url object. (Note that the Symfony browser's functionality of paths
   *   relative to the previous request is not available, because an initial '/'
   *   is assumed if not present.)
   * @param array $options
   *   (optional) Options to be forwarded to the URL generator. The 'absolute'
   *   option is not supported.
   * @param string[] $headers
   *   An array containing additional HTTP request headers, the array keys are
   *   the header names and the array values the header values. This is useful
   *   to set for example the "Accept-Language" header for requesting the page
   *   in a different language. Note that Mink's BrowserKitDriver normalizes
   *   header names to uppercase, while Symfony's HTTP classes normalize to
   *   lower case, which may cause a header to not be found with certain APIs.
   *
   * @return string
   *   The retrieved HTML string.
   *
   * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
   */
  protected function drupalGet($path): string {
  protected function drupalGet($path, array $options = [], array $headers = []): string {
    $session = $this->getSession();

    if (!str_starts_with($path, '/')) {
    if (is_string($path) && !str_starts_with($path, '/')) {
      $path = '/' . $path;
    }

    if (is_object($path) || $options) {
      $path = $this->buildUrl($path, $options);
    }

    foreach ($headers as $header_name => $header_value) {
      assert(is_string($header_name));

      $session->setRequestHeader($header_name, $header_value);
    }

    $session->visit($path);

    $out = $session->getPage()->getContent();
@@ -97,6 +119,34 @@ protected function clickLink(string|\Stringable $label, int $index = 0): void {
    $this->drupalGet($links[$index]->getAttribute('href'));
  }

  /**
   * Builds a URL from a system path or a URL object.
   *
   * @param string|\Drupal\Core\Url $path
   *   A system path or a URL object.
   * @param array $options
   *   Options to be passed to Url::fromUri(). If $path is a Url object, any
   *   options it has will take priority over this parameter.
   *
   * @return string
   *   A URL string.
   */
  protected function buildUrl(Url|string $path, array $options = []): string {
    assert(empty($options['absolute']), 'Absolute URLs are not usable with drupalGet().');

    if ($path instanceof Url) {
      if ($options) {
        $url_options = $path->getOptions();
        $options = $url_options + $options;
        $path->setOptions($options);
      }
      return $path->toString();
    }

    $uri = $path === '<front>' ? 'base:/' : 'base:/' . $path;
    return Url::fromUri($uri, $options)->toString();
  }

  /**
   * Returns Mink session.
   *