3 namespace Drupal\Tests\rest\Functional;
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;
15 * Tests the structure of a REST resource.
19 class ResourceTest extends BrowserTestBase {
26 public static $modules = ['hal', 'rest', 'entity_test', 'rest_test'];
31 * @var \Drupal\Core\Entity\EntityInterface
38 protected function setUp() {
40 // Create an entity programmatic.
41 $this->entity = EntityTest::create([
42 'name' => $this->randomMachineName(),
44 'field_test_text' => [
46 'value' => $this->randomString(),
47 'format' => 'plain_text',
51 $this->entity->save();
53 Role::load(AccountInterface::ANONYMOUS_ROLE)
54 ->grantPermission('view test entity')
59 * Tests that a resource without formats cannot be enabled.
61 public function testFormats() {
62 RestResourceConfig::create([
63 'id' => 'entity.entity_test',
64 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
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.');
85 * Tests that a resource without authentication cannot be enabled.
87 public function testAuthentication() {
88 RestResourceConfig::create([
89 'id' => 'entity.entity_test',
90 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
93 'supported_formats' => [
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.');
111 * Tests that serialization_class is optional.
113 public function testSerializationClassIsOptional() {
114 RestResourceConfig::create([
115 'id' => 'serialization_test',
116 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
119 'supported_formats' => [
122 'supported_auth' => [
128 \Drupal::service('router.builder')->rebuildIfNeeded();
130 Role::load(RoleInterface::ANONYMOUS_ID)
131 ->grantPermission('restful post serialization_test')
134 $serialized = $this->container->get('serializer')->serialize(['foo', 'bar'], 'json');
136 RequestOptions::HEADERS => ['Content-Type' => 'application/json'],
137 RequestOptions::BODY => $serialized,
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());
147 * Tests that resource URI paths are formatted properly.
149 public function testUriPaths() {
150 /** @var \Drupal\rest\Plugin\Type\ResourcePluginManager $manager */
151 $manager = \Drupal::service('plugin.manager.rest');
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.');