3 namespace Drupal\rest\Tests;
5 use Drupal\Core\Session\AccountInterface;
6 use Drupal\rest\RestResourceConfigInterface;
7 use Drupal\user\Entity\Role;
8 use Drupal\user\RoleInterface;
11 * Tests the structure of a REST resource.
15 class ResourceTest extends RESTTestBase {
22 public static $modules = ['hal', 'rest', 'entity_test', 'rest_test'];
27 * @var \Drupal\Core\Entity\EntityInterface
34 protected function setUp() {
36 // Create an entity programmatic.
37 $this->entity = $this->entityCreate('entity_test');
38 $this->entity->save();
40 Role::load(AccountInterface::ANONYMOUS_ROLE)
41 ->grantPermission('view test entity')
46 * Tests that a resource without formats cannot be enabled.
48 public function testFormats() {
49 $this->resourceConfigStorage->create([
50 'id' => 'entity.entity_test',
51 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
61 // Verify that accessing the resource returns 406.
62 $response = $this->httpRequest($this->entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
63 // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
64 // non-REST route a match, but a lower quality one: no format restrictions
65 // means there's always a match and hence when there is no matching REST
66 // route, the non-REST route is used, but can't render into
67 // application/hal+json, so it returns a 406.
68 $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.');
73 * Tests that a resource without authentication cannot be enabled.
75 public function testAuthentication() {
76 $this->resourceConfigStorage->create([
77 'id' => 'entity.entity_test',
78 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
81 'supported_formats' => [
88 // Verify that accessing the resource returns 401.
89 $response = $this->httpRequest($this->entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
90 // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
91 // non-REST route a match, but a lower quality one: no format restrictions
92 // means there's always a match and hence when there is no matching REST
93 // route, the non-REST route is used, but can't render into
94 // application/hal+json, so it returns a 406.
95 $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.');
100 * Tests that serialization_class is optional.
102 public function testSerializationClassIsOptional() {
103 $this->enableService('serialization_test', 'POST', 'json');
105 Role::load(RoleInterface::ANONYMOUS_ID)
106 ->grantPermission('restful post serialization_test')
109 $serialized = $this->container->get('serializer')->serialize(['foo', 'bar'], 'json');
110 $this->httpRequest('serialization_test', 'POST', $serialized, 'application/json');
111 $this->assertResponse(200);
112 $this->assertResponseBody('["foo","bar"]');
116 * Tests that resource URI paths are formatted properly.
118 public function testUriPaths() {
119 $this->enableService('entity:entity_test');
120 /** @var \Drupal\rest\Plugin\Type\ResourcePluginManager $manager */
121 $manager = \Drupal::service('plugin.manager.rest');
123 foreach ($manager->getDefinitions() as $resource => $definition) {
124 foreach ($definition['uri_paths'] as $key => $uri_path) {
125 $this->assertFalse(strpos($uri_path, '//'), 'The resource URI path does not have duplicate slashes.');