jsonapi_cross_bundles-8.x-1.0-alpha3/tests/src/Functional/CrossBundleCollectionTest.php
tests/src/Functional/CrossBundleCollectionTest.php
<?php
namespace Drupal\Tests\jsonapi_cross_bundles\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Url;
use Drupal\entity_test\Entity\EntityTestBundle;
use Drupal\entity_test\Entity\EntityTestWithBundle;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\jsonapi\Functional\JsonApiRequestTestTrait;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
use GuzzleHttp\RequestOptions;
/**
* Tests the cross bundle collection route.
*
* @group jsonapi_cross_bundles
*/
class CrossBundleCollectionTest extends BrowserTestBase {
use JsonApiRequestTestTrait;
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected static $modules = [
'jsonapi_cross_bundles',
'jsonapi_cross_bundles_test',
'entity_test',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->grantPermissions(Role::load(RoleInterface::ANONYMOUS_ID), ['view test entity']);
$this->makeBundle('bundle1');
$this->makeBundle('bundle2');
$this->makeBundle('bundle3');
$bundle1_entity = EntityTestWithBundle::create([
'type' => 'bundle1',
'name' => 'Bundle 1 Test Entity',
]);
$bundle1_entity->save();
$bundle2_entity = EntityTestWithBundle::create([
'type' => 'bundle2',
'name' => 'Bundle 2 Test Entity',
]);
$bundle2_entity->save();
$bundle3_entity = EntityTestWithBundle::create([
'type' => 'bundle3',
'name' => 'Bundle 3 Test Entity',
]);
$bundle3_entity->save();
$this->container->get('router.builder')->rebuild();
}
/**
* Tests the cross bundle collection.
*/
public function testEntityTestWithBundleCrossBundleCollection() {
$url = Url::fromRoute('jsonapi.entity_test_with_bundle.collection');
$request_options = [];
$request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json';
$response = $this->request('GET', $url, $request_options);
$this->assertSame(200, $response->getStatusCode(), var_export(Json::decode((string) $response->getBody()), TRUE));
$this->assertSame(['application/vnd.api+json'], $response->getHeader('Content-Type'));
$response_document = Json::decode((string) $response->getBody());
$this->assertNotNull($response_document);
$data = $response_document['data'];
$this->assertCount(3, $data);
$this->assertEquals([
'entity_test_with_bundle--bundle1',
'entity_test_with_bundle--bundle2',
'entity_test_with_bundle--bundle3',
], array_map(static function (array $item) {
return $item['type'];
}, $data));
$this->assertEquals([
'Bundle 1 Test Entity',
'Bundle 2 Test Entity',
'Bundle 3 Test Entity',
], array_map(static function (array $item) {
return $item['attributes']['name'];
}, $data));
}
/**
* Tests sorting cross bundle collections.
*
* @dataProvider dataProviderCollectionSorts
*/
public function testCrossBundleCollectionWithSort($sort, $expected) {
$url = Url::fromRoute('jsonapi.entity_test_with_bundle.collection', [], [
'query' => [
'sort' => $sort,
],
]);
$request_options = [];
$request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json';
$response = $this->request('GET', $url, $request_options);
$this->assertSame(200, $response->getStatusCode(), var_export(Json::decode((string) $response->getBody()), TRUE));
$this->assertSame(['application/vnd.api+json'], $response->getHeader('Content-Type'));
$response_document = Json::decode((string) $response->getBody());
$this->assertNotNull($response_document);
$data = $response_document['data'];
$this->assertSame($expected, array_map(static function (array $item) {
return $item['attributes']['name'];
}, $data));
}
/**
* Tests filtering cross bundle collections.
*/
public function testCrossBundleCollectionWithFilter() {
$url = Url::fromRoute('jsonapi.entity_test_with_bundle.collection', [], [
'query' => [
'filter' => [
'name' => 'Bundle 2 Test Entity',
],
],
]);
$request_options = [];
$request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json';
$response = $this->request('GET', $url, $request_options);
$this->assertSame(200, $response->getStatusCode(), var_export(Json::decode((string) $response->getBody()), TRUE));
$this->assertSame(['application/vnd.api+json'], $response->getHeader('Content-Type'));
$response_document = Json::decode((string) $response->getBody());
$this->assertNotNull($response_document);
$data = $response_document['data'];
$this->assertCount(1, $data, var_export($response_document, TRUE));
$this->assertEquals('Bundle 2 Test Entity', $data[0]['attributes']['name']);
}
/**
* Data provider for collection sort test.
*
* @return \Generator
*/
public function dataProviderCollectionSorts() {
yield [
'name',
[
'Bundle 1 Test Entity',
'Bundle 2 Test Entity',
'Bundle 3 Test Entity',
],
];
yield [
'-name',
[
'Bundle 3 Test Entity',
'Bundle 2 Test Entity',
'Bundle 1 Test Entity',
],
];
}
/**
* Create a simple bundle.
*
* @param string $name
* The name of the bundle to create.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function makeBundle($name) {
EntityTestBundle::create([
'id' => $name,
])->save();
}
/**
* Creates a field for a specified entity type/bundle.
*
* @param string $type
* The field type.
* @param string $name
* The name of the field to create.
* @param string $entity_type
* The entity type to which the field will be attached.
* @param string[] $bundles
* The entity bundles to which the field will be attached.
* @param array $storage_settings
* Custom storage settings for the field.
* @param array $config_settings
* Custom configuration settings for the field.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function makeField($type, $name, $entity_type, array $bundles, array $storage_settings = [], array $config_settings = []) {
$storage_config = [
'field_name' => $name,
'type' => $type,
'entity_type' => $entity_type,
'settings' => $storage_settings,
];
FieldStorageConfig::create($storage_config)->save();
foreach ($bundles as $bundle) {
FieldConfig::create([
'field_name' => $name,
'entity_type' => $entity_type,
'bundle' => $bundle,
'settings' => $config_settings,
])->save();
}
}
}
