diff --git a/composer.json b/composer.json index 4ed246e4..bc3bea83 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "require": { "drupal/core": "~8.5", "drupal/address": "^1.4", - "drupal/entity": "^1.0-beta3", + "drupal/entity": "1.x-dev", "drupal/entity_reference_revisions": "~1.0", "drupal/inline_entity_form": "^1.0-rc1", "drupal/profile": "~1.0", diff --git a/modules/product/tests/src/Functional/ProductAdminTest.php b/modules/product/tests/src/Functional/ProductAdminTest.php index 7b99d070..6170dd00 100644 --- a/modules/product/tests/src/Functional/ProductAdminTest.php +++ b/modules/product/tests/src/Functional/ProductAdminTest.php @@ -140,7 +140,7 @@ class ProductAdminTest extends ProductBrowserTestBase { } /** - * Tests that anonymous users cannot see the admin/commerce/products page. + * Tests viewing the admin/commerce/products page. */ public function testAdminProducts() { $this->drupalGet('admin/commerce/products'); @@ -148,6 +148,60 @@ class ProductAdminTest extends ProductBrowserTestBase { $this->assertSession()->pageTextNotContains('You are not authorized to access this page.'); $this->assertNotEmpty($this->getSession()->getPage()->hasLink('Add product')); + // Create a default type product. + $product = $this->createEntity('commerce_product', [ + 'type' => 'default', + 'title' => 'First product', + 'status' => TRUE, + ]); + // Create a second product type and products for that type. + $values = [ + 'id' => 'random', + 'label' => 'Random', + 'description' => 'My random product type', + 'variationType' => 'default', + ]; + $product_type = $this->createEntity('commerce_product_type', $values); + commerce_product_add_stores_field($product_type); + commerce_product_add_variations_field($product_type); + $random_product_1 = $this->createEntity('commerce_product', [ + 'type' => 'random', + 'title' => 'Second product', + 'status' => FALSE, + ]); + $random_product_2 = $this->createEntity('commerce_product', [ + 'type' => 'random', + 'title' => 'Third product', + 'status' => TRUE, + ]); + + $this->drupalGet('admin/commerce/products'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextNotContains('You are not authorized to access this page.'); + $row_count = $this->getSession()->getPage()->findAll('xpath', '//table/tbody/tr'); + $this->assertEquals(3, count($row_count), 'Table has 3 rows.'); + + // Confirm that product titles are displayed. + $page = $this->getSession()->getPage(); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="First product"]'); + $this->assertEquals(1, count($product_count), 'First product is displayed.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Second product"]'); + $this->assertEquals(1, count($product_count), 'Second product is displayed.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Third product"]'); + $this->assertEquals(1, count($product_count), 'Third product is displayed.'); + + // Confirm that product types are displayed. + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Default")]'); + $this->assertEquals(1, count($product_count), 'Default product type exists in the table.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Random")]'); + $this->assertEquals(2, count($product_count), 'Random product types exist in the table.'); + + // Confirm that product statuses are displayed. + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Unpublished")]'); + $this->assertEquals(1, count($product_count), 'Unpublished product exists in the table.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Published")]'); + $this->assertEquals(2, count($product_count), 'Published products exist in the table.'); + // Logout and check that anonymous users cannot see the products page // and receive a 403 error code. $this->drupalLogout(); @@ -155,6 +209,37 @@ class ProductAdminTest extends ProductBrowserTestBase { $this->assertSession()->statusCodeEquals(403); $this->assertSession()->pageTextContains('You are not authorized to access this page.'); $this->assertNotEmpty(!$this->getSession()->getPage()->hasLink('Add product')); + + // Login and confirm access for 'access commerce_product overview' permission. + $user = $this->drupalCreateUser(['access commerce_product overview']); + $this->drupalLogin($user); + $this->drupalGet('admin/commerce/products'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextNotContains('You are not authorized to access this page.'); + $this->assertNotEmpty(!$this->getSession()->getPage()->hasLink('Add product')); + $row_count = $this->getSession()->getPage()->findAll('xpath', '//table/tbody/tr'); + $this->assertEquals(3, count($row_count), 'Table has 3 rows.'); + + // Confirm that product titles are displayed. + $page = $this->getSession()->getPage(); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="First product"]'); + $this->assertEquals(1, count($product_count), 'First product is displayed.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Second product"]'); + $this->assertEquals(1, count($product_count), 'Second product is displayed.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Third product"]'); + $this->assertEquals(1, count($product_count), 'Third product is displayed.'); + + // Confirm that product types are displayed. + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Default")]'); + $this->assertEquals(1, count($product_count), 'Default product type exists in the table.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Random")]'); + $this->assertEquals(2, count($product_count), 'Random product types exist in the table.'); + + // Confirm that product statuses are displayed. + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Unpublished")]'); + $this->assertEquals(1, count($product_count), 'Unpublished product exists in the table.'); + $product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Published")]'); + $this->assertEquals(2, count($product_count), 'Published products exist in the table.'); } } diff --git a/src/CommerceBundleAccessControlHandler.php b/src/CommerceBundleAccessControlHandler.php index 6d7887d9..4547732e 100644 --- a/src/CommerceBundleAccessControlHandler.php +++ b/src/CommerceBundleAccessControlHandler.php @@ -3,30 +3,25 @@ namespace Drupal\commerce; use Drupal\Core\Access\AccessResult; -use Drupal\Core\Entity\EntityAccessControlHandler as CoreEntityAccessControlHandler; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\entity\BundleEntityAccessControlHandler; /** * Defines the access control handler for bundles. */ -class CommerceBundleAccessControlHandler extends CoreEntityAccessControlHandler { +class CommerceBundleAccessControlHandler extends BundleEntityAccessControlHandler { /** * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { - /** @var \Drupal\commerce\Entity\CommerceBundleEntityInterface $entity */ - $admin_permission = $entity->getEntityType()->getAdminPermission(); - if ($operation === 'delete') { - if ($entity->isLocked()) { - return AccessResult::forbidden()->addCacheableDependency($entity); - } - else { - return AccessResult::allowedIfHasPermission($account, $admin_permission)->addCacheableDependency($entity); - } + if ($operation === 'delete' && $entity->isLocked()) { + return AccessResult::forbidden()->addCacheableDependency($entity); + } + else { + return parent::checkAccess($entity, $operation, $account); } - return AccessResult::allowedIfHasPermission($account, $admin_permission); } }