3

When I test my endpoint via POSTMAN, I don't have any problems. When I run my PhpUnitTest I keep getting 404:

1) Drupal\my_dashboard\Tests\Functional\MyDashboardResourceTest::testPost
Failed asserting that 404 is identical to 200.

rest.resource.snap_shots_resource.yml

langcode: en
status: true
dependencies:
  module:
    - serialization
    - user
    - my_dashboard
id: snap_shots_resource
plugin_id: snap_shots_resource
granularity: resource
configuration:
  methods:
    - POST
  formats:
    - json
  authentication:
    - cookie

SnapShotsResource.php

namespace Drupal\my_dashboard\Plugin\rest\resource;

use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Psr\Log\LoggerInterface;

/**
 * Provides a resource to get view modes by entity and bundle.
 *
 * @RestResource(
 *   id = "snap_shots_resource",
 *   label = @Translation("Snap shots resource"),
 *   uri_paths = {
 *     "canonical" = "/snapshots",
 *     "https://www.drupal.org/link-relations/create" = "/snapshots"
 *   }
 * )
 */
class SnapShotsResource extends ResourceBase {

  /**
   * A current user instance.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * Constructs a Drupal\rest\Plugin\ResourceBase object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param array $serializer_formats
   *   The available serialization formats.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   A current user instance.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    array $serializer_formats,
    LoggerInterface $logger,
    AccountProxyInterface $current_user) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);

    $this->currentUser = $current_user;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->getParameter('serializer.formats'),
      $container->get('logger.factory')->get('my_dashboard'),
      $container->get('current_user')
    );
  }

  /**
   * Responds to POST requests.
   *
   * @param array $data
   *   Data array.
   *
   * @return object
   *   Returns ResourceResponse.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\HttpException
   *   Throws exception expected.
   */
  public function post(array $data = []) {
    $response = ['message' => $data];
    return new ResourceResponse($response);
  }

}

Here is my Test class MyDashboardResourceTest:

namespace Drupal\my_dashboard\Tests\Functional;

use \Drupal\Tests\rest\Functional\ResourceTestBase;
use Psr\Http\Message\ResponseInterface;
use Drupal\Core\Url;
use GuzzleHttp\RequestOptions;

/**
 * Tests the My Dashboard Resources.
 *
 * @group rest
 */
class MyDashboardResourceTest extends ResourceTestBase {

  /**
   * Modules to install.
   *
   * @var array
   */
  public static $modules = ['hal', 'rest', 'user', 'serialization', 'my_dashboard'];

  public function testPost() {
    $this->initAuthentication();
    $this->setUpAuthorization('POST');

    $request_options = [];
    $request_options[RequestOptions::HEADERS]['Accept'] = static::$mimeType;
    $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType;
    $request_options[RequestOptions::BODY] = '{}';
    $url = Url::fromUserInput('/snapshots');
    $response = $this->request('POST', $url, $request_options);
    $this->assertSame(200, $response->getStatusCode());
  }

  /**
   * {@inheritdoc}
   */
  protected function setUpAuthorization($method) {
    switch ($method) {
      case 'POST':
        $this->grantPermissionsToTestedRole(['restful post snap_shots_resource']);
        break;
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function getExpectedUnauthorizedAccessMessage($method) {
    switch ($method) {
      case 'POST':
        return "The 'restful post snap shots resource' permission is required.";
      default:
        return parent::getExpectedUnauthorizedAccessMessage($method);
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function getExpectedBcUnauthorizedAccessMessage($method) {
    return "The 'restful " . strtolower($method) . " requires snapshots permission";
  }

  /**
   * {@inheritdoc}
   */
  protected function assertResponseWhenMissingAuthentication(ResponseInterface $response) {
    throw new \LogicException('When testing for anonymous users, authentication cannot be missing.');
  }

  /**
   * {@inheritdoc}
   */
  protected function assertNormalizationEdgeCases($method, Url $url, array $request_options) {

  }

  /**
   * {@inheritdoc}
   */
  protected function assertAuthenticationEdgeCases($method, Url $url, array $request_options) {

  }


}

1 Answer 1

1

I ended up fixing my issue by not using the ResourceTestBase request method but creating the Client myself:

$url = Url::fromUserInput('/snapshots');
$url = $url->setAbsolute(TRUE)->toString();

$client = new Client();

$request_options = [];
$request_options[RequestOptions::HEADERS]['Accept'] = static::$mimeType;
$request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType;
$request_options[RequestOptions::BODY] = $this->getBody();

// Tests good post.
$response = $client->request('POST', $url, $request_options);
$this->assertSame(200, $response->getStatusCode());
$this->assertSession()->statusCodeEquals(200);
1
  • Oh man i've been smashing my head over this issue for days. For some reason even just using their $this->getHttpClient() doesn't seem to work either.
    – blu
    Commented Jul 26, 2022 at 15:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.