Problem/Motivation

I have a Functional test in a custom module which test a feeds response. For this I am intercepting the original api call to provide test data and to intercept call I am using a custom service in a test module with that service tagged as http_client_middleware .

it worked fine with 200 response but throws exception with 403 response

Steps to reproduce

Below is the files I have created
Test file - docroot/modules/custom/feed_custom/tests/src/Functional/FeaturesTest.php

<?php

namespace Drupal\Tests\feed_custom\Functional;

use Drupal\Tests\BrowserTestBase;

/**
 * Test for specific features.
 *
 * @group feed_custom
 */
class FeaturesTest extends BrowserTestBase {
  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'feed_custom',
    'feed_test',
    'dblog',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

  }

  /**
   * Testing the download and import of the custom feed.
   */
  protected function testFeedImport(): void {

    // Set the test data into a state variable.
    $file_path = $this->container->get('extension.path.resolver')->getPath('module', 'feed_custom') . '/tests/fixtures/test_data.json';
    \Drupal::state()->set('feed_custom.test_data', file_get_contents($file_path));
    
// Also set the status code into its own state variable.
    \Drupal::state()->set('feed_custom.status_code', 200);

    // Run Cron (which will run the feed import).
    \Drupal::service('cron')->run();

    // Set the test_data state variable to null.
    // This will replicate the feed returning nothing with a 200 status code.
    \Drupal::state()->set('feed_custom.test_data', NULL);

    // Run cron again.
    // This should hit our "no data returned" message in feed_custom_cron().
    \Drupal::service('cron')->run();

    // Now lets try to replicate a 403 error.
    \Drupal::state()->set('feed_custom.status_code', 403);

    // Run cron again.
    // This will hit our other error message related to a 403.
    \Drupal::service('cron')->run();
  }

}

feed_custom/tests/modules/feed_test/feed_test.services.yml

services:
  feed_test.http_client_middleware:
    class: Drupal\feed_test\TestHttpClientMiddleware
    arguments: ['@state']
    tags:
      - { name: http_client_middleware }

docroot/modules/custom/feed_custom/tests/modules/feed_test/src/TestHttpClientMiddleware.php

<?php

namespace Drupal\feed_test;

use Drupal\Core\State\StateInterface;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\RequestInterface;

/**
 * Overrides the requested endpoint when running tests.
 */
class TestHttpClientMiddleware {

  /**
   * Constructs a new instance.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   The state.
   */
  public function __construct(protected StateInterface $state) {
  }

  /**
   * Invoked method that returns a promise with test data.
   */
  public function __invoke(): \Closure {
    return function ($handler) {
      return function (RequestInterface $request, array $options) use ($handler): PromiseInterface {
        // API requests to feed.
        if (str_contains($request->getUri(), 'https://test.qweb.com')) {
          return $this->createPromise($request);
        }
        // Otherwise, no intervention. We defer to the handler stack.
        return $handler($request, $options);
      };
    };
  }

  /**
   * Creates a promise for the request.
   */
  protected function createPromise(RequestInterface $request): PromiseInterface {
    $response = new Response($this->state->get('feed_custom.status_code'), [], $this->state->get('feed_custom.test_data'));
    return new FulfilledPromise($response);
  }

}

Here in the createPromise() function when value of $this->state->get('feed_custom.status_code') is 200 it works fine but when value of $this->state->get('feed_custom.status_code') is other than 200 it throws exception as below

GuzzleHttp\Exception\ClientException: Client error: `Get https://test.qweb.com/getData` resulted in a `403 Forbidden` response in GuzzleHttp\Exception\RequestException::create() (line 113 of /vendor/guzzlehttp/guzzle/src/Exception/RequestException.php).

Any suggestions/help would be greatly appreciated!

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Comments

nitesh624 created an issue. See original summary.

nitesh624’s picture

Issue summary: View changes
nitesh624’s picture

Issue summary: View changes
quietone’s picture

Version: 10.3.x-dev » 11.x-dev
Issue tags: -GuzzleHttp Exception, -http_client_middleware, -GuzzleHttp Error

Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to our policies.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.