protected static function ResourceResponseTestTrait::toCollectionResourceResponse in JSON:API 8
Same name and namespace in other branches
- 8.2 tests/src/Functional/ResourceResponseTestTrait.php \Drupal\Tests\jsonapi\Functional\ResourceResponseTestTrait::toCollectionResourceResponse()
Merges individual responses into a collection response.
Here, a collection response refers to a response with multiple resource objects. Not necessarily to a response to a collection route. In both cases, the document should indistinguishable.
Parameters
array $responses: An array or ResourceResponses to be merged.
string|null $self_link: The self link for the merged document if one should be set.
bool $is_multiple: Whether the responses are for a multiple cardinality field. This cannot be deduced from the number of responses, because a multiple cardinality field may have only one value.
Return value
\Drupal\jsonapi\ResourceResponse The merged ResourceResponse.
3 calls to ResourceResponseTestTrait::toCollectionResourceResponse()
- ResourceResponseTestTrait::getExpectedIncludedResourceResponse in tests/
src/ Functional/ ResourceResponseTestTrait.php - Gets an array of expected ResourceResponses for the given include paths.
- ResourceTestBase::getExpectedCollectionResponse in tests/
src/ Functional/ ResourceTestBase.php - Returns a JSON API collection document for the expected entities.
- ResourceTestBase::getExpectedRelatedResponses in tests/
src/ Functional/ ResourceTestBase.php - Builds an array of expected related ResourceResponses, keyed by field name.
File
- tests/
src/ Functional/ ResourceResponseTestTrait.php, line 42
Class
- ResourceResponseTestTrait
- Utility methods for handling resource responses.
Namespace
Drupal\Tests\jsonapi\FunctionalCode
protected static function toCollectionResourceResponse(array $responses, $self_link, $is_multiple) {
assert(count($responses) > 0);
$merged_document = [];
$merged_cacheability = new CacheableMetadata();
foreach ($responses as $response) {
$response_document = $response
->getResponseData();
$merge_errors = function ($errors) use (&$merged_document, $is_multiple) {
foreach ($errors as $error) {
if ($is_multiple) {
$merged_document['meta']['errors'][] = $error;
}
else {
$merged_document['errors'][] = $error;
}
}
};
// If any of the response documents had top-level or meta errors, we
// should later expect the merged document to have all these errors
// under the 'meta' member.
if (!empty($response_document['errors'])) {
$merge_errors($response_document['errors']);
}
if (!empty($response_document['meta']['errors'])) {
$merge_errors($response_document['meta']['errors']);
}
elseif (isset($response_document['data'])) {
$response_data = $response_document['data'];
if (!isset($merged_document['data'])) {
$merged_document['data'] = static::isResourceIdentifier($response_data) && $is_multiple ? [
$response_data,
] : $response_data;
}
else {
$response_resources = static::isResourceIdentifier($response_data) ? [
$response_data,
] : $response_data;
foreach ($response_resources as $response_resource) {
$merged_document['data'][] = $response_resource;
}
}
}
$merged_cacheability
->addCacheableDependency($response
->getCacheableMetadata());
}
// Until we can reasonably know what caused an error, we shouldn't include
// 'self' links in error documents. For example, a 404 shouldn't have a
// 'self' link because HATEOAS links shouldn't point to resources which do
// not exist.
if (isset($merged_document['errors'])) {
unset($merged_document['links']);
}
else {
$merged_document['links'] = [
'self' => $self_link,
];
// @todo Assign this to every document, even with errors in https://www.drupal.org/project/jsonapi/issues/2949807
$merged_document['jsonapi'] = [
'meta' => [
'links' => [
'self' => 'http://jsonapi.org/format/1.0/',
],
],
'version' => '1.0',
];
}
// If any successful code exists, use that one. Partial success isn't
// defined by HTTP semantics. When different response codes exist, fall
// back to a more general code. Any one success will make the merged request
// a success.
$merged_response_code = array_reduce($responses, function ($merged_response_code, $response) {
$response_code = $response
->getStatusCode();
assert($response_code >= 200 && $response_code < 500, 'Responses must be valid and complete to be merged.');
assert(!($response_code >= 300 && $response_code < 400), 'Redirect responses cannot be merged.');
// In the initial case, use the first response code.
if (is_null($merged_response_code)) {
return $response_code;
}
elseif ($merged_response_code === $response_code) {
return $merged_response_code;
}
elseif ($response_code >= 200 && $response_code < 300 || $merged_response_code >= 200 && $merged_response_code < 300) {
return 200;
}
else {
return 400;
}
}, NULL);
return (new ResourceResponse($merged_document, $merged_response_code))
->addCacheableDependency($merged_cacheability);
}