Skip to content
Snippets Groups Projects
Verified Commit f944ef3f authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #3052931 by gabesullice, Wim Leers, larowlan: Permit arrays as target...

Issue #3052931 by gabesullice, Wim Leers, larowlan: Permit arrays as target attribute values in Drupal\jsonapi\JsonApiResource\Link
parent 32f4d3e4
No related branches found
No related tags found
No related merge requests found
......@@ -76,9 +76,7 @@ public function __construct(CacheableMetadata $cacheability, Url $url, array $li
assert(/* !empty($link_relation_types) && */Inspector::assertAllStrings($link_relation_types));
assert(Inspector::assertAllStrings(array_keys($target_attributes)));
assert(Inspector::assertAll(function ($target_attribute_value) {
return is_string($target_attribute_value)
|| is_array($target_attribute_value)
&& Inspector::assertAllStrings($target_attribute_value);
return is_string($target_attribute_value) || is_array($target_attribute_value);
}, array_values($target_attributes)));
$generated_url = $url->setAbsolute()->toString(TRUE);
$this->href = $generated_url->getGeneratedUrl();
......@@ -160,17 +158,7 @@ public static function compare(Link $a, Link $b) {
public static function merge(Link $a, Link $b) {
assert(static::compare($a, $b) === 0);
$merged_rels = array_unique(array_merge($a->getLinkRelationTypes(), $b->getLinkRelationTypes()));
$merged_attributes = $a->getTargetAttributes();
foreach ($b->getTargetAttributes() as $key => $value) {
if (isset($merged_attributes[$key])) {
// The attribute values can be either a string or an array of strings.
$value = array_unique(array_merge(
is_string($merged_attributes[$key]) ? [$merged_attributes[$key]] : $merged_attributes[$key],
is_string($value) ? [$value] : $value
));
}
$merged_attributes[$key] = count($value) === 1 ? reset($value) : $value;
}
$merged_attributes = array_merge_recursive($a->getTargetAttributes(), $b->getTargetAttributes());
$merged_cacheability = (new CacheableMetadata())->addCacheableDependency($a)->addCacheableDependency($b);
return new static($merged_cacheability, $a->getUri(), $merged_rels, $merged_attributes);
}
......
<?php
namespace Drupal\Tests\jsonapi\Unit\JsonApiResource;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\GeneratedUrl;
use Drupal\Core\Url;
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
use Drupal\jsonapi\JsonApiResource\Link;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\jsonapi\JsonApiResource\Link
* @group jsonapi
*
* @internal
*/
class LinkTest extends UnitTestCase {
/**
* @covers ::merge
* @dataProvider mergeTargetAttributesProvider
*/
public function testMergeTargetAttributes($a, $b, $expected) {
$this->assertSame($expected->getTargetAttributes(), Link::merge($a, $b)->getTargetAttributes());
}
/**
* Provides test data for link merging.
*/
public function mergeTargetAttributesProvider() {
$cases = [
'strings' => [
['key' => 'foo'],
['key' => 'bar'],
['key' => ['foo', 'bar']],
],
'string and array' => [
['key' => 'foo'],
['key' => ['bar', 'baz']],
['key' => ['foo', 'bar', 'baz']],
],
'one-dimensional indexed arrays' => [
['key' => ['foo']],
['key' => ['bar']],
['key' => ['foo', 'bar']],
],
'one-dimensional keyed arrays' => [
['key' => ['foo' => 'tball']],
['key' => ['bar' => 'ista']],
[
'key' => [
'foo' => 'tball',
'bar' => 'ista',
],
],
],
'two-dimensional indexed arrays' => [
['one' => ['two' => ['foo']]],
['one' => ['two' => ['bar']]],
['one' => ['two' => ['foo', 'bar']]],
],
'two-dimensional keyed arrays' => [
['one' => ['two' => ['foo' => 'tball']]],
['one' => ['two' => ['bar' => 'ista']]],
[
'one' => [
'two' => [
'foo' => 'tball',
'bar' => 'ista',
],
],
],
],
];
$this->mockUrlAssembler();
return array_map(function ($arguments) {
return array_map(function ($attributes) {
return new Link(new CacheableMetadata(), Url::fromUri('https://jsonapi.org/'), ['item'], $attributes);
}, $arguments);
}, $cases);
}
/**
* Mocks the unrouted URL assembler.
*/
protected function mockUrlAssembler() {
$url_assembler = $this->getMockBuilder(UnroutedUrlAssemblerInterface::class)
->disableOriginalConstructor()
->getMock();
$url_assembler->method('assemble')->willReturn((new GeneratedUrl())->setGeneratedUrl('https://jsonapi.org/'));
$container = new ContainerBuilder();
$container->set('unrouted_url_assembler', $url_assembler);
\Drupal::setContainer($container);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment