Skip to content

Commit 65345a8

Browse files
lisastreeterbojanz
authored andcommitted
Issue #2949235 by lisastreeter, bojanz: Bundle entity types (product type, order type, etc) need to support the "view label" access check
1 parent c3f4f64 commit 65345a8

3 files changed

Lines changed: 94 additions & 14 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"require": {
88
"drupal/core": "~8.5",
99
"drupal/address": "^1.4",
10-
"drupal/entity": "^1.0-beta3",
10+
"drupal/entity": "^1.0-beta4",
1111
"drupal/entity_reference_revisions": "~1.0",
1212
"drupal/inline_entity_form": "^1.0-rc1",
1313
"drupal/profile": "~1.0",

modules/product/tests/src/Functional/ProductAdminTest.php

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,21 +140,106 @@ public function testDeleteProduct() {
140140
}
141141

142142
/**
143-
* Tests that anonymous users cannot see the admin/commerce/products page.
143+
* Tests viewing the admin/commerce/products page.
144144
*/
145145
public function testAdminProducts() {
146146
$this->drupalGet('admin/commerce/products');
147147
$this->assertSession()->statusCodeEquals(200);
148148
$this->assertSession()->pageTextNotContains('You are not authorized to access this page.');
149149
$this->assertNotEmpty($this->getSession()->getPage()->hasLink('Add product'));
150150

151+
// Create a default type product.
152+
$product = $this->createEntity('commerce_product', [
153+
'type' => 'default',
154+
'title' => 'First product',
155+
'status' => TRUE,
156+
]);
157+
// Create a second product type and products for that type.
158+
$values = [
159+
'id' => 'random',
160+
'label' => 'Random',
161+
'description' => 'My random product type',
162+
'variationType' => 'default',
163+
];
164+
$product_type = $this->createEntity('commerce_product_type', $values);
165+
commerce_product_add_stores_field($product_type);
166+
commerce_product_add_variations_field($product_type);
167+
$this->createEntity('commerce_product', [
168+
'type' => 'random',
169+
'title' => 'Second product',
170+
'status' => FALSE,
171+
]);
172+
$this->createEntity('commerce_product', [
173+
'type' => 'random',
174+
'title' => 'Third product',
175+
'status' => TRUE,
176+
]);
177+
178+
$this->drupalGet('admin/commerce/products');
179+
$this->assertSession()->statusCodeEquals(200);
180+
$this->assertSession()->pageTextNotContains('You are not authorized to access this page.');
181+
$row_count = $this->getSession()->getPage()->findAll('xpath', '//table/tbody/tr');
182+
$this->assertEquals(3, count($row_count), 'Table has 3 rows.');
183+
184+
// Confirm that product titles are displayed.
185+
$page = $this->getSession()->getPage();
186+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="First product"]');
187+
$this->assertEquals(1, count($product_count), 'First product is displayed.');
188+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Second product"]');
189+
$this->assertEquals(1, count($product_count), 'Second product is displayed.');
190+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Third product"]');
191+
$this->assertEquals(1, count($product_count), 'Third product is displayed.');
192+
193+
// Confirm that product types are displayed.
194+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Default")]');
195+
$this->assertEquals(1, count($product_count), 'Default product type exists in the table.');
196+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Random")]');
197+
$this->assertEquals(2, count($product_count), 'Random product types exist in the table.');
198+
199+
// Confirm that product statuses are displayed.
200+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Unpublished")]');
201+
$this->assertEquals(1, count($product_count), 'Unpublished product exists in the table.');
202+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Published")]');
203+
$this->assertEquals(2, count($product_count), 'Published products exist in the table.');
204+
151205
// Logout and check that anonymous users cannot see the products page
152206
// and receive a 403 error code.
153207
$this->drupalLogout();
154208
$this->drupalGet('admin/commerce/products');
155209
$this->assertSession()->statusCodeEquals(403);
156210
$this->assertSession()->pageTextContains('You are not authorized to access this page.');
157211
$this->assertNotEmpty(!$this->getSession()->getPage()->hasLink('Add product'));
212+
213+
// Login and confirm access for 'access commerce_product overview' permission.
214+
$user = $this->drupalCreateUser(['access commerce_product overview']);
215+
$this->drupalLogin($user);
216+
$this->drupalGet('admin/commerce/products');
217+
$this->assertSession()->statusCodeEquals(200);
218+
$this->assertSession()->pageTextNotContains('You are not authorized to access this page.');
219+
$this->assertNotEmpty(!$this->getSession()->getPage()->hasLink('Add product'));
220+
$row_count = $this->getSession()->getPage()->findAll('xpath', '//table/tbody/tr');
221+
$this->assertEquals(3, count($row_count), 'Table has 3 rows.');
222+
223+
// Confirm that product titles are displayed.
224+
$page = $this->getSession()->getPage();
225+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="First product"]');
226+
$this->assertEquals(1, count($product_count), 'First product is displayed.');
227+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Second product"]');
228+
$this->assertEquals(1, count($product_count), 'Second product is displayed.');
229+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td/a[text()="Third product"]');
230+
$this->assertEquals(1, count($product_count), 'Third product is displayed.');
231+
232+
// Confirm that product types are displayed.
233+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Default")]');
234+
$this->assertEquals(1, count($product_count), 'Default product type exists in the table.');
235+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Random")]');
236+
$this->assertEquals(2, count($product_count), 'Random product types exist in the table.');
237+
238+
// Confirm that product statuses are displayed.
239+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Unpublished")]');
240+
$this->assertEquals(1, count($product_count), 'Unpublished product exists in the table.');
241+
$product_count = $page->findAll('xpath', '//table/tbody/tr/td[starts-with(text(), "Published")]');
242+
$this->assertEquals(2, count($product_count), 'Published products exist in the table.');
158243
}
159244

160245
}

src/CommerceBundleAccessControlHandler.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,25 @@
33
namespace Drupal\commerce;
44

55
use Drupal\Core\Access\AccessResult;
6-
use Drupal\Core\Entity\EntityAccessControlHandler as CoreEntityAccessControlHandler;
76
use Drupal\Core\Entity\EntityInterface;
87
use Drupal\Core\Session\AccountInterface;
8+
use Drupal\entity\BundleEntityAccessControlHandler;
99

1010
/**
1111
* Defines the access control handler for bundles.
1212
*/
13-
class CommerceBundleAccessControlHandler extends CoreEntityAccessControlHandler {
13+
class CommerceBundleAccessControlHandler extends BundleEntityAccessControlHandler {
1414

1515
/**
1616
* {@inheritdoc}
1717
*/
1818
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
19-
/** @var \Drupal\commerce\Entity\CommerceBundleEntityInterface $entity */
20-
$admin_permission = $entity->getEntityType()->getAdminPermission();
21-
if ($operation === 'delete') {
22-
if ($entity->isLocked()) {
23-
return AccessResult::forbidden()->addCacheableDependency($entity);
24-
}
25-
else {
26-
return AccessResult::allowedIfHasPermission($account, $admin_permission)->addCacheableDependency($entity);
27-
}
19+
if ($operation === 'delete' && $entity->isLocked()) {
20+
return AccessResult::forbidden()->addCacheableDependency($entity);
21+
}
22+
else {
23+
return parent::checkAccess($entity, $operation, $account);
2824
}
29-
return AccessResult::allowedIfHasPermission($account, $admin_permission);
3025
}
3126

3227
}

0 commit comments

Comments
 (0)