1e8babe0db20aa9cbad1184c87c8f8b23372cbdb
[yaffs-website] / web / core / modules / rest / tests / src / Functional / ResourceTest.php
1 <?php
2
3 namespace Drupal\Tests\rest\Functional;
4
5 use Drupal\Core\Session\AccountInterface;
6 use Drupal\entity_test\Entity\EntityTest;
7 use Drupal\rest\Entity\RestResourceConfig;
8 use Drupal\rest\RestResourceConfigInterface;
9 use Drupal\Tests\BrowserTestBase;
10 use Drupal\user\Entity\Role;
11 use Drupal\user\RoleInterface;
12 use GuzzleHttp\RequestOptions;
13
14 /**
15  * Tests the structure of a REST resource.
16  *
17  * @group rest
18  */
19 class ResourceTest extends BrowserTestBase {
20
21   /**
22    * Modules to install.
23    *
24    * @var array
25    */
26   public static $modules = ['hal', 'rest', 'entity_test', 'rest_test'];
27
28   /**
29    * The entity.
30    *
31    * @var \Drupal\Core\Entity\EntityInterface
32    */
33   protected $entity;
34
35   /**
36    * {@inheritdoc}
37    */
38   protected function setUp() {
39     parent::setUp();
40     // Create an entity programmatic.
41     $this->entity = EntityTest::create([
42       'name' => $this->randomMachineName(),
43       'user_id' => 1,
44       'field_test_text' => [
45         0 => [
46           'value' => $this->randomString(),
47           'format' => 'plain_text',
48         ],
49       ],
50     ]);
51     $this->entity->save();
52
53     Role::load(AccountInterface::ANONYMOUS_ROLE)
54       ->grantPermission('view test entity')
55       ->save();
56   }
57
58   /**
59    * Tests that a resource without formats cannot be enabled.
60    */
61   public function testFormats() {
62     RestResourceConfig::create([
63       'id' => 'entity.entity_test',
64       'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
65       'configuration' => [
66         'GET' => [
67           'supported_auth' => [
68             'basic_auth',
69           ],
70         ],
71       ],
72     ])->save();
73
74     // Verify that accessing the resource returns 406.
75     $this->drupalGet($this->entity->urlInfo()->setRouteParameter('_format', 'hal_json'));
76     // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
77     // non-REST route a match, but a lower quality one: no format restrictions
78     // means there's always a match and hence when there is no matching REST
79     // route, the non-REST route is used, but can't render into
80     // application/hal+json, so it returns a 406.
81     $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.');
82   }
83
84   /**
85    * Tests that a resource without authentication cannot be enabled.
86    */
87   public function testAuthentication() {
88     RestResourceConfig::create([
89       'id' => 'entity.entity_test',
90       'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
91       'configuration' => [
92         'GET' => [
93           'supported_formats' => [
94             'hal_json',
95           ],
96         ],
97       ],
98     ])->save();
99
100     // Verify that accessing the resource returns 401.
101     $this->drupalGet($this->entity->urlInfo()->setRouteParameter('_format', 'hal_json'));
102     // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
103     // non-REST route a match, but a lower quality one: no format restrictions
104     // means there's always a match and hence when there is no matching REST
105     // route, the non-REST route is used, but can't render into
106     // application/hal+json, so it returns a 406.
107     $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.');
108   }
109
110   /**
111    * Tests that serialization_class is optional.
112    */
113   public function testSerializationClassIsOptional() {
114     RestResourceConfig::create([
115       'id' => 'serialization_test',
116       'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
117       'configuration' => [
118         'POST' => [
119           'supported_formats' => [
120             'json',
121           ],
122           'supported_auth' => [
123             'cookie',
124           ]
125         ],
126       ],
127     ])->save();
128     \Drupal::service('router.builder')->rebuildIfNeeded();
129
130     Role::load(RoleInterface::ANONYMOUS_ID)
131       ->grantPermission('restful post serialization_test')
132       ->save();
133
134     $serialized = $this->container->get('serializer')->serialize(['foo', 'bar'], 'json');
135     $request_options = [
136       RequestOptions::HEADERS => ['Content-Type' => 'application/json'],
137       RequestOptions::BODY => $serialized,
138     ];
139     /** @var \GuzzleHttp\ClientInterface $client */
140     $client = $this->getSession()->getDriver()->getClient()->getClient();
141     $response = $client->request('POST', $this->buildUrl('serialization_test', ['query' => ['_format' => 'json']]), $request_options);
142     $this->assertSame(200, $response->getStatusCode());
143     $this->assertSame('["foo","bar"]', (string) $response->getBody());
144   }
145
146   /**
147    * Tests that resource URI paths are formatted properly.
148    */
149   public function testUriPaths() {
150     /** @var \Drupal\rest\Plugin\Type\ResourcePluginManager $manager */
151     $manager = \Drupal::service('plugin.manager.rest');
152
153     foreach ($manager->getDefinitions() as $resource => $definition) {
154       foreach ($definition['uri_paths'] as $key => $uri_path) {
155         $this->assertFalse(strpos($uri_path, '//'), 'The resource URI path does not have duplicate slashes.');
156       }
157     }
158   }
159
160 }