From c815e002b1447406cfac1b88ac31303eac4441a0 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Mon, 25 Mar 2024 10:31:31 +0000 Subject: [PATCH] Issue #3088870 by amateescu, Wim Leers, Spokje, jofitz, alexpott: Add missing REST and JSON:API test coverage for the workspace entity type --- core/modules/jsonapi/jsonapi.module | 2 +- .../tests/src/Functional/ResourceTestBase.php | 40 ++- .../tests/src/Functional/WorkspaceTest.php | 264 ++++++++++++++++++ .../src/WorkspaceAccessControlHandler.php | 15 +- .../WorkspaceJsonAnonTest.php | 2 +- .../WorkspaceJsonBasicAuthTest.php | 2 +- .../WorkspaceJsonCookieTest.php | 2 +- .../WorkspaceResourceTestBase.php | 27 +- .../WorkspaceXmlAnonTest.php | 2 +- .../WorkspaceXmlBasicAuthTest.php | 2 +- .../WorkspaceXmlCookieTest.php | 2 +- 11 files changed, 333 insertions(+), 27 deletions(-) create mode 100644 core/modules/jsonapi/tests/src/Functional/WorkspaceTest.php rename core/modules/workspaces/tests/src/Functional/{EntityResource => Rest}/WorkspaceJsonAnonTest.php (89%) rename core/modules/workspaces/tests/src/Functional/{EntityResource => Rest}/WorkspaceJsonBasicAuthTest.php (91%) rename core/modules/workspaces/tests/src/Functional/{EntityResource => Rest}/WorkspaceJsonCookieTest.php (90%) rename core/modules/workspaces/tests/src/Functional/{EntityResource => Rest}/WorkspaceResourceTestBase.php (83%) rename core/modules/workspaces/tests/src/Functional/{EntityResource => Rest}/WorkspaceXmlAnonTest.php (92%) rename core/modules/workspaces/tests/src/Functional/{EntityResource => Rest}/WorkspaceXmlBasicAuthTest.php (94%) rename core/modules/workspaces/tests/src/Functional/{EntityResource => Rest}/WorkspaceXmlCookieTest.php (93%) diff --git a/core/modules/jsonapi/jsonapi.module b/core/modules/jsonapi/jsonapi.module index 395c292eea35..4d9f8b82894f 100644 --- a/core/modules/jsonapi/jsonapi.module +++ b/core/modules/jsonapi/jsonapi.module @@ -310,7 +310,7 @@ function jsonapi_jsonapi_user_filter_access(EntityTypeInterface $entity_type, Ac /** * Implements hook_jsonapi_ENTITY_TYPE_filter_access() for 'workspace'. */ -function jsonapi_jsonapi_workspace_filter_access(EntityTypeInterface $entity_type, $published, $owner, AccountInterface $account) { +function jsonapi_jsonapi_workspace_filter_access(EntityTypeInterface $entity_type, AccountInterface $account) { // @see \Drupal\workspaces\WorkspaceAccessControlHandler::checkAccess() return ([ JSONAPI_FILTER_AMONG_ALL => AccessResult::allowedIfHasPermission($account, 'view any workspace'), diff --git a/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php b/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php index 6227961eeb76..ff14e5a3722e 100644 --- a/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php +++ b/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php @@ -432,9 +432,19 @@ protected function getEntityDuplicate(EntityInterface $original, $key) { if ($label_key = $original->getEntityType()->getKey('label')) { $duplicate->set($label_key, $original->label() . '_' . $key); } - if ($duplicate instanceof ConfigEntityInterface && $id_key = $duplicate->getEntityType()->getKey('id')) { - $id = $original->id(); - $duplicate->set($id_key, $id . '_' . $key); + + $id_key = $duplicate->getEntityType()->getKey('id'); + $needs_manual_id = $duplicate instanceof ConfigEntityInterface && $id_key; + + if ($duplicate instanceof FieldableEntityInterface && $id_key) { + $id_field = $duplicate->getFieldDefinition($id_key); + if ($id_field->getType() !== 'integer') { + $needs_manual_id = TRUE; + } + } + + if ($needs_manual_id) { + $duplicate->set($id_key, $original->id() . '_' . $key); } return $duplicate; } @@ -938,7 +948,9 @@ public function testGetIndividual() { $expected_403_cacheability = $this->getExpectedUnauthorizedAccessCacheability(); $reason = $this->getExpectedUnauthorizedAccessMessage('GET'); $message = trim("The current user is not allowed to GET the selected resource. $reason"); - $this->assertResourceErrorResponse(403, $message, $url, $response, '/data', $expected_403_cacheability->getCacheTags(), $expected_403_cacheability->getCacheContexts(), FALSE, 'MISS'); + // MISS or UNCACHEABLE depends on data. It must not be HIT. + $dynamic_cache_header_value = !empty(array_intersect(['user', 'session'], $expected_403_cacheability->getCacheContexts())) ? 'UNCACHEABLE' : 'MISS'; + $this->assertResourceErrorResponse(403, $message, $url, $response, '/data', $expected_403_cacheability->getCacheTags(), $expected_403_cacheability->getCacheContexts(), FALSE, $dynamic_cache_header_value); $this->assertArrayNotHasKey('Link', $response->getHeaders()); } else { @@ -1089,7 +1101,7 @@ public function testCollection() { $expected_cacheability = $expected_response->getCacheableMetadata(); $response = $this->request('HEAD', $collection_url, $request_options); // MISS or UNCACHEABLE depends on the collection data. It must not be HIT. - $dynamic_cache = $expected_cacheability->getCacheMaxAge() === 0 ? 'UNCACHEABLE' : 'MISS'; + $dynamic_cache = $expected_cacheability->getCacheMaxAge() === 0 || !empty(array_intersect(['user', 'session'], $expected_cacheability->getCacheContexts())) ? 'UNCACHEABLE' : 'MISS'; $this->assertResourceResponse(200, NULL, $response, $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, $dynamic_cache); // Different databases have different sort orders, so a sort is required so @@ -1102,6 +1114,8 @@ public function testCollection() { // self::getExpectedCollectionResponse(). $expected_response = $this->getExpectedCollectionResponse($entity_collection, $collection_url->toString(), $request_options); $expected_cacheability = $expected_response->getCacheableMetadata(); + // MISS or UNCACHEABLE depends on the collection data. It must not be HIT. + $dynamic_cache = $expected_cacheability->getCacheMaxAge() === 0 || !empty(array_intersect(['user', 'session'], $expected_cacheability->getCacheContexts())) ? 'UNCACHEABLE' : 'MISS'; $expected_document = $expected_response->getResponseData(); $response = $this->request('GET', $collection_url, $request_options); $this->assertResourceResponse(200, $expected_document, $response, $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, $dynamic_cache); @@ -1111,6 +1125,8 @@ public function testCollection() { // 200 for well-formed HEAD request. $expected_response = $this->getExpectedCollectionResponse($entity_collection, $collection_url->toString(), $request_options); $expected_cacheability = $expected_response->getCacheableMetadata(); + // MISS or UNCACHEABLE depends on the collection data. It must not be HIT. + $dynamic_cache = $expected_cacheability->getCacheMaxAge() === 0 || !empty(array_intersect(['user', 'session'], $expected_cacheability->getCacheContexts())) ? 'UNCACHEABLE' : 'MISS'; $response = $this->request('HEAD', $collection_url, $request_options); $this->assertResourceResponse(200, NULL, $response, $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, $dynamic_cache); @@ -1387,7 +1403,7 @@ protected function doTestRelated(array $request_options) { FALSE, $actual_response->getStatusCode() === 200 ? ($expected_cacheability->getCacheMaxAge() === 0 ? 'UNCACHEABLE' : 'MISS') - : FALSE + : (!empty(array_intersect(['user', 'session'], $expected_cacheability->getCacheContexts())) ? 'UNCACHEABLE' : FALSE) ); } } @@ -1422,7 +1438,9 @@ protected function doTestRelationshipGet(array $request_options) { $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, - $expected_resource_response->isSuccessful() ? 'MISS' : FALSE + empty(array_intersect(['user', 'session'], $expected_cacheability->getCacheContexts())) + ? $expected_resource_response->isSuccessful() ? 'MISS' : FALSE + : 'UNCACHEABLE' ); } } @@ -2874,7 +2892,9 @@ public function testRevisions() { if ($result instanceof AccessResultReasonInterface && ($reason = $result->getReason()) && !empty($reason)) { $detail .= ' ' . $reason; } - $this->assertResourceErrorResponse(403, $detail, $url, $actual_response, '/data', $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, 'MISS'); + // MISS or UNCACHEABLE depends on data. It must not be HIT. + $dynamic_cache = !empty(array_intersect(['user', 'session'], $expected_cacheability->getCacheContexts())) ? 'UNCACHEABLE' : 'MISS'; + $this->assertResourceErrorResponse(403, $detail, $url, $actual_response, '/data', $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, $dynamic_cache); // Ensure that targeting a revision does not bypass access. $actual_response = $this->request('GET', $original_revision_id_url, $request_options); @@ -2883,7 +2903,9 @@ public function testRevisions() { if ($result instanceof AccessResultReasonInterface && ($reason = $result->getReason()) && !empty($reason)) { $detail .= ' ' . $reason; } - $this->assertResourceErrorResponse(403, $detail, $url, $actual_response, '/data', $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, 'MISS'); + // MISS or UNCACHEABLE depends on data. It must not be HIT. + $dynamic_cache = !empty(array_intersect(['user', 'session'], $expected_cacheability->getCacheContexts())) ? 'UNCACHEABLE' : 'MISS'; + $this->assertResourceErrorResponse(403, $detail, $url, $actual_response, '/data', $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), FALSE, $dynamic_cache); $this->setUpRevisionAuthorization('GET'); diff --git a/core/modules/jsonapi/tests/src/Functional/WorkspaceTest.php b/core/modules/jsonapi/tests/src/Functional/WorkspaceTest.php new file mode 100644 index 000000000000..05e5ca13f6f4 --- /dev/null +++ b/core/modules/jsonapi/tests/src/Functional/WorkspaceTest.php @@ -0,0 +1,264 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\jsonapi\Functional; + +use Drupal\Core\Cache\CacheableMetadata; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Url; +use Drupal\user\Entity\User; +use Drupal\workspaces\Entity\Workspace; + +/** + * JSON:API integration test for the "Workspace" content entity type. + * + * @group jsonapi + * @group #slow + */ +class WorkspaceTest extends ResourceTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['workspaces']; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * {@inheritdoc} + */ + protected static $entityTypeId = 'workspace'; + + /** + * {@inheritdoc} + */ + protected static $resourceTypeName = 'workspace--workspace'; + + /** + * {@inheritdoc} + */ + protected static $resourceTypeIsVersionable = TRUE; + + /** + * {@inheritdoc} + */ + protected static $patchProtectedFieldNames = [ + 'changed' => NULL, + ]; + + /** + * {@inheritdoc} + */ + protected static $uniqueFieldNames = ['id']; + + /** + * {@inheritdoc} + */ + protected static $firstCreatedEntityId = 'autumn_campaign'; + + /** + * {@inheritdoc} + */ + protected static $secondCreatedEntityId = 'autumn_campaign'; + + /** + * {@inheritdoc} + * + * @var \Drupal\workspaces\WorkspaceInterface + */ + protected $entity; + + /** + * {@inheritdoc} + */ + protected function setUpAuthorization($method): void { + switch ($method) { + case 'GET': + $this->grantPermissionsToTestedRole(['view any workspace']); + break; + + case 'POST': + $this->grantPermissionsToTestedRole(['create workspace']); + break; + + case 'PATCH': + $this->grantPermissionsToTestedRole(['edit any workspace']); + break; + + case 'DELETE': + $this->grantPermissionsToTestedRole(['delete any workspace']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity(): EntityInterface { + $entity = Workspace::create([ + 'id' => 'campaign', + 'label' => 'Campaign', + 'uid' => $this->account->id(), + 'created' => 123456789, + ]); + $entity->save(); + return $entity; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedDocument(): array { + $author = User::load($this->entity->getOwnerId()); + $base_url = Url::fromUri('base:/jsonapi/workspace/workspace/' . $this->entity->uuid())->setAbsolute(); + $self_url = clone $base_url; + $version_identifier = 'id:' . $this->entity->getRevisionId(); + $self_url = $self_url->setOption('query', ['resourceVersion' => $version_identifier]); + $version_query_string = '?resourceVersion=' . urlencode($version_identifier); + return [ + 'jsonapi' => [ + 'meta' => [ + 'links' => [ + 'self' => ['href' => 'http://jsonapi.org/format/1.0/'], + ], + ], + 'version' => '1.0', + ], + 'links' => [ + 'self' => ['href' => $base_url->toString()], + ], + 'data' => [ + 'id' => $this->entity->uuid(), + 'type' => static::$resourceTypeName, + 'links' => [ + 'self' => ['href' => $self_url->toString()], + ], + 'attributes' => [ + 'created' => '1973-11-29T21:33:09+00:00', + 'changed' => (new \DateTime())->setTimestamp($this->entity->getChangedTime())->setTimezone(new \DateTimeZone('UTC'))->format(\DateTime::RFC3339), + 'label' => 'Campaign', + 'drupal_internal__id' => 'campaign', + 'drupal_internal__revision_id' => 2, + ], + 'relationships' => [ + 'parent' => [ + 'data' => NULL, + 'links' => [ + 'related' => [ + 'href' => $base_url->toString() . '/parent' . $version_query_string, + ], + 'self' => [ + 'href' => $base_url->toString() . '/relationships/parent' . $version_query_string, + ], + ], + ], + 'uid' => [ + 'data' => [ + 'id' => $author->uuid(), + 'meta' => [ + 'drupal_internal__target_id' => (int) $author->id(), + ], + 'type' => 'user--user', + ], + 'links' => [ + 'related' => [ + 'href' => $base_url->toString() . '/uid' . $version_query_string, + ], + 'self' => [ + 'href' => $base_url->toString() . '/relationships/uid' . $version_query_string, + ], + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getPostDocument(): array { + return [ + 'data' => [ + 'type' => static::$resourceTypeName, + 'attributes' => [ + 'drupal_internal__id' => 'autumn_campaign', + 'label' => 'Autumn campaign', + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getModifiedEntityForPostTesting() { + $modified = parent::getModifiedEntityForPostTesting(); + // Even though the field type of the workspace ID is 'string', it acts as a + // machine name through a custom constraint, so we need to ensure that we + // generate a proper random value for it. + // @see \Drupal\workspaces\Entity\Workspace::baseFieldDefinitions() + $modified['data']['attributes']['id'] = $this->randomMachineName(); + return $modified; + } + + /** + * {@inheritdoc} + */ + protected function getPatchDocument(): array { + $patch_document = parent::getPatchDocument(); + unset($patch_document['data']['attributes']['drupal_internal__id']); + return $patch_document; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessCacheability(): CacheableMetadata { + // @see \Drupal\workspaces\WorkspaceAccessControlHandler::checkAccess() + return parent::getExpectedUnauthorizedAccessCacheability() + ->addCacheTags(['workspace:campaign']) + // The "view|edit|delete own workspace" permissions add the 'user' cache + // context. + ->addCacheContexts(['user']); + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method): string { + switch ($method) { + case 'GET': + return "The 'view own workspace' permission is required."; + + case 'POST': + return "The following permissions are required: 'administer workspaces' OR 'create workspace'."; + + case 'PATCH': + return "The 'edit own workspace' permission is required."; + + case 'DELETE': + return "The 'delete own workspace' permission is required."; + + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + + /** + * {@inheritdoc} + */ + protected function getSparseFieldSets(): array { + // Workspace's resource type name ('workspace') comes after the 'uid' field, + // which breaks nested sparse fieldset tests. + return array_diff_key(parent::getSparseFieldSets(), array_flip([ + 'nested_empty_fieldset', + 'nested_fieldset_with_owner_fieldset', + ])); + } + +} diff --git a/core/modules/workspaces/src/WorkspaceAccessControlHandler.php b/core/modules/workspaces/src/WorkspaceAccessControlHandler.php index af95857a32e2..2bedf5b56297 100644 --- a/core/modules/workspaces/src/WorkspaceAccessControlHandler.php +++ b/core/modules/workspaces/src/WorkspaceAccessControlHandler.php @@ -30,7 +30,20 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter // @todo Consider adding explicit "publish any|own workspace" permissions in // https://www.drupal.org/project/drupal/issues/3084260. - $permission_operation = ($operation === 'update' || $operation === 'publish') ? 'edit' : $operation; + switch ($operation) { + case 'update': + case 'publish': + $permission_operation = 'edit'; + break; + + case 'view all revisions': + $permission_operation = 'view'; + break; + + default: + $permission_operation = $operation; + break; + } // Check if the user has permission to access all workspaces. $access_result = AccessResult::allowedIfHasPermission($account, $permission_operation . ' any workspace'); diff --git a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonAnonTest.php b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonAnonTest.php similarity index 89% rename from core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonAnonTest.php rename to core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonAnonTest.php index e248ce31ed36..854ea1d019b9 100644 --- a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonAnonTest.php +++ b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonAnonTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Drupal\Tests\workspaces\Functional\EntityResource; +namespace Drupal\Tests\workspaces\Functional\Rest; use Drupal\Tests\rest\Functional\AnonResourceTestTrait; diff --git a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonBasicAuthTest.php b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonBasicAuthTest.php similarity index 91% rename from core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonBasicAuthTest.php rename to core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonBasicAuthTest.php index b30d7cdacac5..365c8a9474e9 100644 --- a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonBasicAuthTest.php +++ b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonBasicAuthTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Drupal\Tests\workspaces\Functional\EntityResource; +namespace Drupal\Tests\workspaces\Functional\Rest; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; diff --git a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonCookieTest.php b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonCookieTest.php similarity index 90% rename from core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonCookieTest.php rename to core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonCookieTest.php index f36087e4ccfe..9129c1468117 100644 --- a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonCookieTest.php +++ b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceJsonCookieTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Drupal\Tests\workspaces\Functional\EntityResource; +namespace Drupal\Tests\workspaces\Functional\Rest; use Drupal\Tests\rest\Functional\CookieResourceTestTrait; diff --git a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceResourceTestBase.php b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceResourceTestBase.php similarity index 83% rename from core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceResourceTestBase.php rename to core/modules/workspaces/tests/src/Functional/Rest/WorkspaceResourceTestBase.php index 000836c39475..b998af426b25 100644 --- a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceResourceTestBase.php +++ b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceResourceTestBase.php @@ -2,16 +2,16 @@ declare(strict_types=1); -namespace Drupal\Tests\workspaces\Functional\EntityResource; +namespace Drupal\Tests\workspaces\Functional\Rest; -use Drupal\Tests\rest\Functional\EntityResource\ConfigEntityResourceTestBase; +use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase; use Drupal\user\Entity\User; use Drupal\workspaces\Entity\Workspace; /** * Base class for workspace EntityResource tests. */ -abstract class WorkspaceResourceTestBase extends ConfigEntityResourceTestBase { +abstract class WorkspaceResourceTestBase extends EntityResourceTestBase { /** * {@inheritdoc} @@ -165,13 +165,7 @@ protected function getNormalizedPostEntity() { * {@inheritdoc} */ protected function getNormalizedPatchEntity() { - return [ - 'label' => [ - [ - 'value' => 'Running on faith', - ], - ], - ]; + return array_diff_key($this->getNormalizedPostEntity(), ['id' => TRUE]); } /** @@ -195,4 +189,17 @@ protected function getExpectedUnauthorizedAccessMessage($method) { return parent::getExpectedUnauthorizedAccessMessage($method); } + /** + * {@inheritdoc} + */ + protected function getModifiedEntityForPostTesting() { + $modified = parent::getModifiedEntityForPostTesting(); + // Even though the field type of the workspace ID is 'string', it acts as a + // machine name through a custom constraint, so we need to ensure that we + // generate a proper random value for it. + // @see \Drupal\workspaces\Entity\Workspace::baseFieldDefinitions() + $modified['id'] = [$this->randomMachineName()]; + return $modified; + } + } diff --git a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlAnonTest.php b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlAnonTest.php similarity index 92% rename from core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlAnonTest.php rename to core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlAnonTest.php index b28f5a47412d..930e917dbbbd 100644 --- a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlAnonTest.php +++ b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlAnonTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Drupal\Tests\workspaces\Functional\EntityResource; +namespace Drupal\Tests\workspaces\Functional\Rest; use Drupal\Tests\rest\Functional\AnonResourceTestTrait; use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait; diff --git a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlBasicAuthTest.php b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlBasicAuthTest.php similarity index 94% rename from core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlBasicAuthTest.php rename to core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlBasicAuthTest.php index d2554ba096e6..eacd4ac49ef4 100644 --- a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlBasicAuthTest.php +++ b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlBasicAuthTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Drupal\Tests\workspaces\Functional\EntityResource; +namespace Drupal\Tests\workspaces\Functional\Rest; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait; diff --git a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlCookieTest.php b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlCookieTest.php similarity index 93% rename from core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlCookieTest.php rename to core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlCookieTest.php index acece12a7a9d..5f064f7163d8 100644 --- a/core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceXmlCookieTest.php +++ b/core/modules/workspaces/tests/src/Functional/Rest/WorkspaceXmlCookieTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Drupal\Tests\workspaces\Functional\EntityResource; +namespace Drupal\Tests\workspaces\Functional\Rest; use Drupal\Tests\rest\Functional\CookieResourceTestTrait; use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait; -- GitLab