I'm trying to filter on product variations in my JSON:API request, which doesn't return data. It's possible that the JSON:API access hook needs to be implemented for variations, because variations use an access handler that doesn't leverage Entity API.

Issue fork commerce-3128322

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

stephenplatz created an issue. See original summary.

mglaman’s picture

Entity API received a fix that solves JSON:API's custom entity access for all entity types extending the Entity API access control.

Variations do not use this access control, because we solve their access as an embedded entity. See https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/produ...

The hook is hook_jsonapi_entity_filter_access.

The Entity API issue was [##3021930]

mglaman’s picture

Assigned: Unassigned » mglaman

Working on this

mglaman’s picture

Status: Active » Needs review
Issue tags: -jsonapi +Needs tests
FileSize
1.25 KB

Needs tests. But with manual testing this fixes it. Maybe we can cherry-pick into Commerce API as well.

mglaman’s picture

Assigned: mglaman » Unassigned
Priority: Normal » Major

Actually, this has a bigger impact. It also fixes the results returned on the variations relationship for a product. Currently inactive variations are returned, and this fixes it to exclude inactive variations.

mglaman’s picture

Wrong issue for this comment

mglaman’s picture

Version: 8.x-2.16 » 8.x-2.x-dev
FileSize
12.9 KB

Here is a test only patch.

mglaman’s picture

Status: Needs review » Needs work

The last submitted patch, 8: 3128322-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mglaman’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
13.21 KB

Adds number comparator.

mglaman’s picture

This will pass because we don't test the filtered collection. It is not out of the box so we need to copy \Drupal\Tests\jsonapi\Functional\NodeTest::testCollectionFilterAccess

Status: Needs review » Needs work

The last submitted patch, 11: 3128322-11-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mglaman’s picture

Turns out Drupal\commerce_price\Comparator\NumberComparator will not help us here. the ResourceTestbase uses assertSame which doesn't load any of the registered Comparator and just uses IsIdentical

mglaman’s picture

Status: Needs work » Needs review
FileSize
13.21 KB

Changed $4.00 to $4.15 to avoid 0 precision differences.

Status: Needs review » Needs work

The last submitted patch, 15: 3128322-15-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mglaman’s picture

That didn't work. Overriding assertSameDocument to use assertEquals

mglaman’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 17: 3128322-17-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mglaman’s picture

This is also, apparently, automatically fixed by Entity 1.1 which adds a generic query access handler to all entities.

mglaman’s picture

Status: Needs work » Needs review
FileSize
17.18 KB

Okay, the changes in entity:1.1 are what prevented this from failing and showing we need #5.

Status: Needs review » Needs work

The last submitted patch, 21: 3128322-21-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mglaman’s picture

Okay, this fixes usages of $this->resourceType from ResourceTestBase (hacked core locally, forgot to override in test.)

This also tries to add a normalizer for price.number when testing with MySQL.

Status: Needs review » Needs work

The last submitted patch, 23: 3128322-23.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mglaman’s picture

Another attempt at a test normalization due to #3163853: ResourceTestBase should use assertEquals over assertSame when comparing data.


  1. +++ b/modules/price/tests/modules/commerce_price_test/commerce_price_test.services.yml
    @@ -3,3 +3,8 @@ services:
    +      # The priority must be higher than serialization.normalizer.field_item.
    

    This comment is incorrect, it runs before the primitive normalizer.

  2. +++ b/modules/product/commerce_product.module
    @@ -358,3 +361,13 @@ function commerce_product_commerce_condition_info_alter(array &$definitions) {
    +/**
    + * Implements hook_jsonapi_ENTITY_TYPE_filter_access().
    + */
    

    Should we comment that this is needed since we do not have a query_access handler?

  3. +++ b/modules/product/src/Entity/Product.php
    @@ -279,7 +279,7 @@ class Product extends CommerceContentEntityBase implements ProductInterface {
    -      if ($variation->product_id->isEmpty()) {
    +      if ($variation && $variation->product_id->isEmpty()) {
    

    Somehow the JSON:API testing had deleted the variation and the product was stale and no longer had a valid reference.

  4. +++ b/modules/product/src/ProductVariationAccessControlHandler.php
    @@ -36,12 +36,14 @@ class ProductVariationAccessControlHandler extends CoreEntityAccessControlHandle
    +      assert($result instanceof AccessResult);
    +      $result->addCacheableDependency($entity);
    ...
    +      $result = AccessResult::allowedIfHasPermission($account, "manage $bundle commerce_product_variation")->cachePerPermissions();
    

    Fixes cache expectations from JSON:API. Which means we maybe had a bug and it could go into its own issue.

  5. +++ b/modules/product/tests/modules/commerce_product_test/commerce_product_test.module
    @@ -21,3 +21,14 @@ function commerce_product_test_entity_access(EntityInterface $entity, $operation
    +  // Remove the EventOnlyQueryAccessHandler added to all entities in entity:1.1
    +  // for testing.
    +  if ($hook === 'entity_type_alter') {
    +    unset($implementations['entity']);
    +  }
    

    I wonder if the generic query_access handler is actually causing more problems than just in this test.

  6. +++ b/modules/product/tests/src/Functional/Jsonapi/ProductVariationResourceTest.php
    @@ -0,0 +1,445 @@
    +  }
    +  /**
    

    missing empty line

  7. +++ b/modules/product/tests/src/Functional/Jsonapi/ProductVariationResourceTest.php
    @@ -0,0 +1,445 @@
    +   * Overridden to use `assertEquals` due to how decimal numbers are handled
    +   * between \json_encode and SQL storages.
    

    Comment is wrong. We might be able to remove this, now, that we have the normalizer.

mglaman’s picture

Addressed my self review. We were able to drop that test method override due to the price normalizer.

mglaman’s picture

mglaman credited jsacksick.

mglaman’s picture

Crediting @jsacksick for rubber ducking over Slack

  • mglaman committed 5d41f57 on 8.x-2.x
    Issue #3128322 by mglaman, jsacksick: Filtering variations over JSON:API...
mglaman’s picture

Status: Needs review » Postponed

Committed!

mglaman’s picture

Status: Postponed » Fixed

Wrong status.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

jsacksick’s picture

FileSize
20.16 KB

Attaching a patch that applies to 2.20