assertResourceErrorResponse example

$config->set('verify_mail', 0);
    $config->save();
    $user = $this->registerUser('Palmer.Eldritch');
    $this->assertFalse($user->isBlocked());
    $this->assertNotEmpty($user->getPassword());
    $email_count = count($this->drupalGetMails());

    $this->assertEquals(0, $email_count);

    // Attempt to register without sending a password.     $response = $this->registerRequest('Rick.Deckard', FALSE);
    $this->assertResourceErrorResponse(422, "No password provided.", $response);

    // Attempt to register with a password when e-mail verification is on.     $config->set('register', UserInterface::REGISTER_VISITORS);
    $config->set('verify_mail', 1);
    $config->save();
    $response = $this->registerRequest('Estraven');
    $this->assertResourceErrorResponse(422, 'A Password cannot be specified. It will be generated on login.', $response);

    // Allow visitors to register with email verification.     $config->set('register', UserInterface::REGISTER_VISITORS);
    $config->set('verify_mail', 1);
    
if ($this->entity->getEntityType()->hasKey('bundle')) {
      $fieldName = static::$fieldName;

      // DX: 422 when 'value' data type is incorrect.       $normalization = $this->getNormalizedPostEntity();
      $normalization[static::$fieldName][0]['value'] = [
        '2017', '03', '01', '21', '53', '00',
      ];
      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);
      $response = $this->request($method$url$request_options);
      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0.value: This value should be of the correct primitive type.\n";
      $this->assertResourceErrorResponse(422, $message$response);

      // DX: 422 when 'end_value' is not specified.       $normalization = $this->getNormalizedPostEntity();
      unset($normalization[static::$fieldName][0]['end_value']);
      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);
      $response = $this->request($method$url$request_options);
      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0.end_value: This value should not be null.\n";
      $this->assertResourceErrorResponse(422, $message$response);

      // DX: 422 when 'end_value' data type is incorrect.       $normalization = $this->getNormalizedPostEntity();
      
// - \Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber applies       // to cacheable anonymous responses: it updates their cacheability.       // - A 403 response to a GET request is cacheable.       // Therefore we must update our cacheability expectations accordingly.       if (in_array('user.permissions', $expected_cookie_403_cacheability->getCacheContexts(), TRUE)) {
        $expected_cookie_403_cacheability->addCacheTags(['config:user.role.anonymous']);
      }
      // @todo Fix \Drupal\block\BlockAccessControlHandler::mergeCacheabilityFromConditions() in https://www.drupal.org/node/2867881       if (static::$entityTypeId === 'block') {
        $expected_cookie_403_cacheability->setCacheTags(str_replace('user:2', 'user:0', $expected_cookie_403_cacheability->getCacheTags()));
      }
      $this->assertResourceErrorResponse(403, FALSE, $response$expected_cookie_403_cacheability->getCacheTags()$expected_cookie_403_cacheability->getCacheContexts(), 'MISS', FALSE);
    }
    else {
      $this->assertResourceErrorResponse(403, FALSE, $response);
    }
  }

  /** * {@inheritdoc} */
  protected function assertAuthenticationEdgeCases($method, Url $url, array $request_options) {
    // X-CSRF-Token request header is unnecessary for safe and side effect-free
$url->setOption('query', ['_format' => static::$format]);
    $request_options = [];
    $request_options[RequestOptions::HEADERS] = [
      // Set the required (and only accepted) content type for the request.       'Content-Type' => 'application/octet-stream',
      // Set the required Content-Disposition header for the file name.       'Content-Disposition' => 'file; filename="drupal rocks 🤘.txt"',
    ];
    $request_options[RequestOptions::BODY] = 'Drupal is the best!';
    $request_options = NestedArray::mergeDeep($request_options$this->getAuthenticationRequestOptions('POST'));
    $response = $this->request('POST', $url$request_options);
    $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('POST')$response);

    // Grant necessary permission, retry.     $this->grantPermissionsToTestedRole(['create camelids media']);
    $response = $this->request('POST', $url$request_options);
    $this->assertSame(201, $response->getStatusCode());
    $expected = $this->getExpectedNormalizedFileEntity();
    static::recursiveKSort($expected);
    $actual = $this->serializer->decode((string) $response->getBody()static::$format);
    static::recursiveKSort($actual);
    $this->assertSame($expected$actual);

    
$url->setOption('query', ['_format' => static::$format]);

    // DX: 404 when resource not provisioned, 403 if canonical route. Non-HTML     // response because ?_format query string is present.     $response = $this->request('GET', $url$request_options);
    if ($has_canonical_url) {
      $expected_cacheability = $this->getExpectedUnauthorizedAccessCacheability()
        // @see \Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber::onRespond()         ->addCacheTags(['config:user.role.anonymous']);
      $expected_cacheability->addCacheableDependency($this->getExpectedUnauthorizedEntityAccessCacheability(FALSE));
      $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET')$response$expected_cacheability->getCacheTags()$expected_cacheability->getCacheContexts(), 'MISS', FALSE);
    }
    else {
      $this->assertResourceErrorResponse(404, 'No route found for "GET ' . $this->getEntityResourceUrl()->setAbsolute()->toString() . '"', $response);
    }

    $this->provisionEntityResource();

    // DX: forgetting authentication: authentication provider-specific error     // response.     if (static::$auth) {
      $response = $this->request('GET', $url$request_options);
      
$document['data']['attributes']['link']['options'] = "O:44:\"Symfony\\Component\\Process\\Pipes\\WindowsPipes\":8:{s:51:\"\\Symfony\\Component\\Process\\Pipes\\WindowsPipes\0files\";a:1:{i:0;s:3:\"foo\";}s:57:\"\0Symfony\\Component\\Process\\Pipes\\WindowsPipes\0fileHandles\";a:0:{}s:55:\"\0Symfony\\Component\\Process\\Pipes\\WindowsPipes\0readBytes\";a:2:{i:1;i:0;i:2;i:0;}s:59:\"\0Symfony\\Component\\Process\\Pipes\\WindowsPipes\0disableOutput\";b:0;s:5:\"pipes\";a:0:{}s:58:\"\0Symfony\\Component\\Process\\Pipes\\AbstractPipes\0inputBuffer\";s:0:\"\";s:52:\"\0Symfony\\Component\\Process\\Pipes\\AbstractPipes\0input\";N;s:54:\"\0Symfony\\Component\\Process\\Pipes\\AbstractPipes\0blocked\";b:1;}";
    $url = Url::fromRoute(sprintf('jsonapi.%s.collection.post', static::$resourceTypeName));
    $request_options = [];
    $request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json';
    $request_options[RequestOptions::HEADERS]['Content-Type'] = 'application/vnd.api+json';
    $request_options[RequestOptions::BODY] = Json::encode($document);
    $request_options = NestedArray::mergeDeep($request_options$this->getAuthenticationRequestOptions());

    // Ensure 403 when unauthorized.     $response = $this->request('POST', $url$request_options);
    $reason = $this->getExpectedUnauthorizedAccessMessage('POST');
    $this->assertResourceErrorResponse(403, (string) $reason$url$response);

    $this->setUpAuthorization('POST');

    // Ensure that an exception is thrown.     $response = $this->request('POST', $url$request_options);
    $this->assertResourceErrorResponse(500, (string) 'The generic FieldItemNormalizer cannot denormalize string values for "options" properties of the "link" field (field item class: Drupal\link\Plugin\Field\FieldType\LinkItem).', $url$response);

    // Create a menu link content entity without the serialized property.     unset($document['data']['attributes']['link']['options']);
    $request_options[RequestOptions::BODY] = Json::encode($document);
    $response = $this->request('POST', $url$request_options);
    
public function testApiJsonNotSupportedInRest() {
    $this->assertSame(['json', 'xml']$this->container->getParameter('serializer.formats'));

    $this->provisionResource(['api_json'][]);
    $this->setUpAuthorization('GET');

    $url = Node::load(1)->toUrl()
      ->setOption('query', ['_format' => 'api_json']);
    $request_options = [];

    $response = $this->request('GET', $url$request_options);
    $this->assertResourceErrorResponse(
      400,
      FALSE,
      $response,
      ['4xx-response', 'config:system.logging', 'config:user.role.anonymous', 'http_response', 'node:1'],
      ['url.query_args:_format', 'url.site', 'user.permissions'],
      'MISS',
      'MISS'
    );
  }

  /** * {@inheritdoc} */
$fieldName = static::$fieldName;

      // DX: 422 when date type is incorrect.       $normalization = $this->getNormalizedPostEntity();
      $normalization[static::$fieldName][0]['value'] = [
        '2017', '03', '01', '21', '53', '00',
      ];

      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);
      $response = $this->request($method$url$request_options);
      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value must be a string.\n{$fieldName}.0.value: This value should be of the correct primitive type.\n";
      $this->assertResourceErrorResponse(422, $message$response);

      // DX: 422 when date format is incorrect.       $normalization = $this->getNormalizedPostEntity();
      $value = '2017-03-01';
      $normalization[static::$fieldName][0]['value'] = $value;

      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);
      $response = $this->request($method$url$request_options);
      $message = "The specified date \"$value\" is not in an accepted format: \"Y-m-d\\TH:i:sP\" (RFC 3339), \"Y-m-d\\TH:i:sO\" (ISO 8601).";
      $this->assertResourceErrorResponse(422, $message$response);

      
RequestOptions::HEADERS => ['Content-Type' => static::$mimeType],
    ];
    $request_options = array_merge_recursive($request_options$this->getAuthenticationRequestOptions('PATCH'));

    // Test case 1: changing email.     $normalization = $original_normalization;
    $normalization['mail'] = [['value' => 'new-email@example.com']];
    $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);

    // DX: 422 when changing email without providing the password.     $response = $this->request('PATCH', $url$request_options);
    $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response, FALSE, FALSE, FALSE, FALSE);

    $normalization['pass'] = [['existing' => 'wrong']];
    $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);

    // DX: 422 when changing email while providing a wrong password.     $response = $this->request('PATCH', $url$request_options);
    $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response, FALSE, FALSE, FALSE, FALSE);

    $normalization['pass'] = [['existing' => $this->account->passRaw]];
    $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);

    
$request_options[RequestOptions::HEADERS]['Content-Type'] = 'application/vnd.api+json';
    $request_options = NestedArray::mergeDeep($request_options$this->getAuthenticationRequestOptions());

    $remove_field = function Darray $normalization$type$attribute_name) {
      unset($normalization['data'][$type][$attribute_name]);
      return $normalization;
    };

    // DX: 422 when missing 'entity_type' field.     $request_options[RequestOptions::BODY] = Json::encode($remove_field($this->getPostDocument(), 'attributes', 'entity_type'));
    $response = $this->request('POST', $url$request_options);
    $this->assertResourceErrorResponse(422, 'entity_type: This value should not be null.', NULL, $response, '/data/attributes/entity_type');

    // DX: 422 when missing 'entity_id' field.     $request_options[RequestOptions::BODY] = Json::encode($remove_field($this->getPostDocument(), 'relationships', 'entity_id'));
    // @todo Remove the try/catch in https://www.drupal.org/node/2820364.     try {
      $response = $this->request('POST', $url$request_options);
      $this->assertResourceErrorResponse(422, 'entity_id: This value should not be null.', NULL, $response, '/data/attributes/entity_id');
    }
    catch (\Exception $e) {
      $this->assertSame("Error: Call to a member function get() on null\nDrupal\\comment\\Plugin\\Validation\\Constraint\\CommentNameConstraintValidator->getAnonymousContactDetailsSetting()() (Line: 96)\n", $e->getMessage());
    }

    
    // field that is forbidden by an implementation of     // hook_jsonapi_entity_field_filter_access() .     $response = $this->request('GET', $collection_filter_url$request_options);
    $message = "The current user is not authorized to filter by the `spotlight` field, given in the path `spotlight`.";
    $expected_cache_tags = ['4xx-response', 'http_response'];
    $expected_cache_contexts = [
      'url.query_args:filter',
      'url.query_args:sort',
      'url.site',
      'user.permissions',
    ];
    $this->assertResourceErrorResponse(403, $message$collection_filter_url$response, FALSE, $expected_cache_tags$expected_cache_contexts, FALSE, 'MISS');
    // And ensure the it is allowed when the proper permission is granted.     $this->grantPermissionsToTestedRole(['filter by spotlight field']);
    $response = $this->request('GET', $collection_filter_url$request_options);
    $doc = Json::decode((string) $response->getBody());
    $this->assertCount(1, $doc['data']);
    $this->assertSame($referencing_entity->uuid()$doc['data'][0]['id']);
    $this->revokePermissionsFromTestedRole(['filter by spotlight field']);

    $this->assertTrue($this->container->get('module_installer')->uninstall(['jsonapi_test_field_filter_access'], TRUE), 'Uninstalled modules.');

    return $referencing_entity;
  }
$fieldName = static::$fieldName;

      // DX: 422 when date type is incorrect.       $normalization = $this->getNormalizedPostEntity();
      $normalization[static::$fieldName][0]['value'] = [
        '2017', '03', '01',
      ];

      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);
      $response = $this->request($method$url$request_options);
      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value must be a string.\n{$fieldName}.0.value: This value should be of the correct primitive type.\n";
      $this->assertResourceErrorResponse(422, $message$response);

      // DX: 422 when date format is incorrect.       $normalization = $this->getNormalizedPostEntity();
      $value = '2017-03-01T01:02:03';
      $normalization[static::$fieldName][0]['value'] = $value;

      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalizationstatic::$format);
      $response = $this->request($method$url$request_options);
      $message = "The specified date \"$value\" is not in an accepted format: \"Y-m-d\" (date-only).";
      $this->assertResourceErrorResponse(422, $message$response);

      
'headers' => [
        'Authorization' => 'Basic ' . base64_encode($this->account->name->value . ':' . $this->account->passRaw),
      ],
    ];
  }

  /** * {@inheritdoc} */
  protected function assertResponseWhenMissingAuthentication($method, ResponseInterface $response) {
    if ($method !== 'GET') {
      return $this->assertResourceErrorResponse(401, 'No authentication credentials provided.', $response);
    }

    $expected_page_cache_header_value = $method === 'GET' ? 'MISS' : FALSE;
    $expected_cacheability = $this->getExpectedUnauthorizedAccessCacheability()
      ->addCacheableDependency($this->getExpectedUnauthorizedEntityAccessCacheability(FALSE))
      // @see \Drupal\basic_auth\Authentication\Provider\BasicAuth::challengeException()       ->addCacheableDependency($this->config('system.site'))
      // @see \Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber::onRespond()       ->addCacheTags(['config:user.role.anonymous']);
    // Only add the 'user.roles:anonymous' cache context if its parent cache     // context is not already present.
$response = $this->request('GET', $url$request_options);
    $original_normalization = Json::decode((string) $response->getBody());

    // Test case 1: changing email.     $normalization = $original_normalization;
    $normalization['data']['attributes']['mail'] = 'new-email@example.com';
    $request_options[RequestOptions::BODY] = Json::encode($normalization);

    // DX: 405 when read-only mode is enabled.     $response = $this->request('PATCH', $url$request_options);
    $this->assertResourceErrorResponse(405, sprintf("JSON:API is configured to accept only read operations. Site administrators can configure this at %s.", Url::fromUri('base:/admin/config/services/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl())$url$response);
    $this->assertSame(['GET']$response->getHeader('Allow'));

    $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);

    // DX: 422 when changing email without providing the password.     $response = $this->request('PATCH', $url$request_options);
    $this->assertResourceErrorResponse(422, 'mail: Your current password is missing or incorrect; it\'s required to change the Email.', NULL, $response, '/data/attributes/mail');

    $normalization['data']['attributes']['pass']['existing'] = 'wrong';
    $request_options[RequestOptions::BODY] = Json::encode($normalization);

    
// Change node's path alias.     $normalization['data']['attributes']['path']['alias'] .= 's-rule-the-world';

    // Create node PATCH request.     $request_options = $this->getAuthenticationRequestOptions();
    $request_options[RequestOptions::HEADERS]['Content-Type'] = 'application/vnd.api+json';
    $request_options[RequestOptions::BODY] = Json::encode($normalization);

    // PATCH request: 403 when creating URL aliases unauthorized.     $response = $this->request('PATCH', $url$request_options);
    $this->assertResourceErrorResponse(403, "The current user is not allowed to PATCH the selected field (path). The following permissions are required: 'create url aliases' OR 'administer url aliases'.", $url$response, '/data/attributes/path');

    // Grant permission to create URL aliases.     $this->grantPermissionsToTestedRole(['create url aliases']);

    // Repeat PATCH request: 200.     $response = $this->request('PATCH', $url$request_options);
    $this->assertResourceResponse(200, FALSE, $response);
    $updated_normalization = Json::decode((string) $response->getBody());
    $this->assertSame($normalization['data']['attributes']['path']['alias']$updated_normalization['data']['attributes']['path']['alias']);
  }

  
Home | Imprint | This part of the site doesn't use cookies.