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