Comments

gabesullice created an issue. See original summary.

gabesullice’s picture

Updating credits.

gabesullice’s picture

Status: Active » Needs review
Related issues: +#2937961: ResourceType should provide related ResourceTypes
StatusFileSize
new9.23 KB

Status: Needs review » Needs work

The last submitted patch, 3: 2939705-3.patch, failed testing. View results

wim leers’s picture

Title: Do not include internal resource types under `include` » [PP-1] Do not include internal resource types under `include`

Updating title per #3.

gabesullice’s picture

Title: [PP-1] Do not include internal resource types under `include` » Do not include internal resource types under `include`
Status: Needs work » Needs review
wim leers’s picture

Status: Needs review » Needs work
  1. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -108,7 +116,12 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +      // Only add "public" resources.
    

    What do you think about s/"public"/non-internal/? "public" is a term we don't use/is undefined in this context.

    Or, better yet, just … no comment. A detailed explanation can be found in the related methods and interfaces.

  2. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -206,27 +222,42 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +  protected function isInternalResourceType(EntityInterface $entity) {
    

    Why is this helper method necessary?

  3. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -206,27 +222,42 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +   * @param string $field
    

    s/$field/$field_name/

  4. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -206,27 +222,42 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +   *   The internal field name.
    ...
    +   *   The resource type names of the non-internal relatable resource types for
    

    "internal field name" vs "non-internal relatable resource types"

    These are two VERY different kinds of "internal".

  5. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -206,27 +222,42 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +  protected static function getAllowedResourceTypes(ResourceType $resource_type, $field) {
    

    Should be called getAllowedResourceTypeNames().

    That, or the body should remove the array_map().

  6. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -206,27 +222,42 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +    $relationship_field = $resource_type->getInternalName($field);
    

    If $field is already supposed to be an internal field name, then why do we need to call ::getInternalName()?

gabesullice’s picture

StatusFileSize
new2.26 KB
new9.18 KB

1. I just removed it.

The "public" language came from ResourceType::getPublicName() vs. ResourceType::getInternalName(), which I agree is conflating two different meanings of "internal". Perhaps getFieldNameFromAlias and getAliasFromFieldName would have been clearer, but it was introduced before internal data definitions.

2. Small methods can make code more self-documenting and easier to read, which is why I love suggestions like #5 :)

3. 👍

4. I agree, see #1. I'm not sure how we can get around this without changing the ResourceType::getPublicName semantics (which might be a nice thing to do, it's worth discussing).

5. Excellent suggestion, monsieur.

6. Good catch!

gabesullice’s picture

Status: Needs work » Needs review
gabesullice’s picture

StatusFileSize
new630 bytes
new9.19 KB

Further clarified a comment.

wim leers’s picture

#8:

  1. ✔️ + I like "alias" for field names much better.
  2. ✔️ (I think this is the first time ever somebody is quoting Martin Fowler back at me :D Love it :))
  3. ✔️
  4. ✔️
  5. ✔️ (Merci!)
  6. ✔️

  1. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -108,7 +116,11 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
           // Get the referenced entity.
           $entity = $item->get('entity')->getValue();
           // And get the translation in the requested language.
    -      $entity_list[] = $this->entityRepository->getTranslationFromContext($entity);
    +      $translated = $this->entityRepository->getTranslationFromContext($entity);
    +
    +      if (!$this->isInternalResourceType($translated)) {
    +        $entity_list[] = $translated;
    +      }
    

    Nit, but shouldn't we do the "is internal" check before getting the translation and use continue instead? Avoids unnecessary work/is slightly clearer.

  2. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -207,26 +222,40 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +   * Gets a list of allowed resource type names for a specific resource field.
    

    s/resource field/reference field/?

  3. +++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
    @@ -207,26 +222,40 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
    +   *   The resource type names of the non-internal relatable resource types for
    +   *   the given field on the parent resource type.
    

    Nit: Perhaps mention that if the given field is NOT a reference field, that this will just return the empty array?

Once those nits are addressed, this is RTBC.

e0ipso’s picture

+++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
@@ -207,26 +222,40 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
+  protected static function getAllowedResourceTypeNames(ResourceType $resource_type, $field_name) {

Martin Fowler always has something to say.

I've grown to dislike static methods because they are namespaced global functions. Hard to stub and test.

https://www.martinfowler.com/bliki/StaticSubstitution.html


Not suggesting a change, I only wanted to join the party 😝 in #11. This can be committed once @Wim Leers' comments have been addressed.

gabesullice’s picture

StatusFileSize
new2.1 KB
new8.94 KB
  1. Good call.
  2. I just removed the word "resource" as this is the EntityReferenceFieldNormalizer after all.
  3. Added some clarification about what will happen when the field isn't classified as a relationship.

In general, I've been trying to code/comment in the language of the spec over the language of Drupal as much as I can.


@e0ipso, I think the distinction is largely between public/protected static methods. Public methods, like Node::load() should receive all the criticism that Martin Fowler brings up. They are "namespaced global functions". However, protected static methods are entirely different. They're not global at all. They simply indicate that the method doesn't use or mutate $this (how's that for a quote!? :P).

Status: Needs review » Needs work

The last submitted patch, 13: 2939705-13.patch, failed testing. View results

wim leers’s picture

Notice: Undefined variable: translated

Should be an easy fix. Then this is RTBC.

gabesullice’s picture

StatusFileSize
new588 bytes
new8.94 KB

🙃

gabesullice’s picture

Status: Needs work » Needs review
wim leers’s picture

  1. +++ b/tests/src/Unit/Normalizer/EntityReferenceFieldNormalizerTest.php
    @@ -32,6 +32,13 @@ class EntityReferenceFieldNormalizerTest extends UnitTestCase {
    +  protected $fakeType;
    
    @@ -69,15 +76,23 @@ class EntityReferenceFieldNormalizerTest extends UnitTestCase {
    +    $this->fakeType = new ResourceType('fake_entity_type', 'dummy_bundle', NULL);
    

    I was first wondering why we had to make this a property on the test class.

  2. +++ b/tests/src/Unit/Normalizer/EntityReferenceFieldNormalizerTest.php
    @@ -69,15 +76,23 @@ class EntityReferenceFieldNormalizerTest extends UnitTestCase {
    +    $this->fakeType->setRelatableResourceTypes([
    +      'field_dummy' => [$this->fakeType, $internal_type],
    +      'field_dummy_single' => [$this->fakeType, $internal_type],
    +    ]);
    
    @@ -96,7 +111,7 @@ class EntityReferenceFieldNormalizerTest extends UnitTestCase {
    -      'resource_type' => new ResourceType('fake_entity_type', 'dummy_bundle', NULL),
    +      'resource_type' => $this->fakeType,
    

    This is the reason.

One last question:

+++ b/tests/src/Unit/Normalizer/EntityReferenceFieldNormalizerTest.php
@@ -69,15 +76,23 @@ class EntityReferenceFieldNormalizerTest extends UnitTestCase {
+      'field_dummy_single' => [$this->fakeType, $internal_type],

Why do we set this if we're not using it anywhere?

gabesullice’s picture

StatusFileSize
new860 bytes
new8.87 KB

Hm, dunno. Removed.

wim leers’s picture

StatusFileSize
new4.43 KB
new8.87 KB

I extracted a test-only patch from #19. It passes tests, but it should not.

wim leers’s picture

Status: Needs review » Needs work
gabesullice’s picture

Title: Do not include internal resource types under `include` » [PP-1] Do not include internal resource types under `include`
Status: Needs work » Postponed

This requires an internal entity type for testing.

An issue for that has been opened here: #2943209: Mark at least one entity_test entity type as 'internal'

wim leers’s picture

I don't think it make sense to postpone this on #2943209: Mark at least one entity_test entity type as 'internal'. I think this issue can continue by depending on the content_moderation module and use that module's internal entity type for now. We can then have a follow-up for this issue that is blocked on #2943209: Mark at least one entity_test entity type as 'internal' which would use that internal test entity type instead.

e0ipso’s picture

I agree with @Wim Leers. I don't think we should postpone one of our criticals based on a core issue that may (or may not) take months to resolve.

I don't think we should use content_moderation but I will not oppose it. I'd rather have a jsonapi_test module that builds upon entity_test to add that. Core can backport that at their own pace. Then we can deprecate jsonapi_test when #2943209: Mark at least one entity_test entity type as 'internal' is available in all supported core versions.

We can then have a follow-up for this issue that is blocked on #2943209: Mark at least one entity_test entity type as 'internal'


This is what I meant to say the other day in Slack @gabesullice.

gabesullice’s picture

Title: [PP-1] Do not include internal resource types under `include` » Do not include internal resource types under `include`
Status: Postponed » Active

Un-postponing.

gabesullice’s picture

Status: Active » Needs work
StatusFileSize
new3.07 KB
new4.8 KB

These patches depend on: #2943209-13: Mark at least one entity_test entity type as 'internal'

The tests will be skipped in Drupal < 8.5 overall. My next patch is going to add a mirror of EntityTestNoLabel into a jsonapi_entity_test module so we can move forward if #2943209 takes too long to land. This will let us easily change the namespace when/if it finally does land as Mateu suggested in #24.

gabesullice’s picture

Status: Needs work » Needs review
StatusFileSize
new4.58 KB
new6.31 KB

Here's the JSON API only version. The test only patch should fail. The other one should be green.

The interdiff just shows the difference in the test file, not the addition of the test module.

The last submitted patch, 27: 2939705-27.tests_only.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 27: 2939705-27.patch, failed testing. View results

gabesullice’s picture

Status: Needs work » Needs review
StatusFileSize
new1.19 KB
new470 bytes
new6.33 KB
new4.6 KB

Fixing the test group.

Also including the interdiff mentioned in #27.

Edit: Testbot stole my comment number!

wim leers’s picture

Status: Needs review » Needs work
  1. +++ b/tests/modules/jsonapi_entity_test/jsonapi_entity_test.info.yml
    @@ -0,0 +1,9 @@
    +#dependencies:
    +#  - field
    +#  - text
    

    Nit: Let's remove these lines.

  2. +++ b/tests/modules/jsonapi_entity_test/src/Entity/EntityTestNoLabel.php
    @@ -0,0 +1,35 @@
    +class EntityTestNoLabel extends EntityTest {
    

    Let's add a @todo to remove this in the follow-up issue that #23 and #24 refer to.

  3. +++ b/tests/src/Functional/InternalEntitiesTest.php
    @@ -0,0 +1,95 @@
    +  protected static $modules = [
    

    Nit: Missing inheritdoc.

  4. +++ b/tests/src/Functional/InternalEntitiesTest.php
    @@ -0,0 +1,95 @@
    +    $this->testUser = $this->drupalCreateUser([
    

    Nit: Needs to be documented on the test class.

  5. +++ b/tests/src/Functional/InternalEntitiesTest.php
    @@ -0,0 +1,95 @@
    +    $this->testBundle = EntityTestBundle::create([
    

    Nit: Does not need to be an object property (i.e. can become $test_bundle instead of $this->testBundle.)

  6. +++ b/tests/src/Functional/InternalEntitiesTest.php
    @@ -0,0 +1,95 @@
    +    $this->internalEntity = EntityTestNoLabel::create([]);
    

    Nit: Same here.

  7. +++ b/tests/src/Functional/InternalEntitiesTest.php
    @@ -0,0 +1,95 @@
    +    $this->referencerEntity = EntityTestWithBundle::create([
    

    First: this needs to be documented (see two points higher).
    Second: "referencing entity" instead of "referencer entity", I think?

  8. +++ b/tests/src/Functional/InternalEntitiesTest.php
    @@ -0,0 +1,95 @@
    +    $response = $this->jsonapiGetIndividual($this->referencerEntity, ['include' => ['field_internal']]);
    …
    +++ b/tests/src/Functional/InternalEntitiesTest.php
    @@ -0,0 +1,95 @@
    +  protected function jsonapiGetIndividual(EntityInterface $entity, $options = []) {
    

    This seems unnecessarily complex, and the helper function seems to make things even more complex:

    $url = Url::fromRoute(
      'jsonapi.jsonapi_entity_test_nl_label--internal_referencer.individual,
      ['jsonapi_entity_test_nl_label' =>  $this->referencingEntity->uuid(),
      ['query' => ['include' => ['field_internal']]]
    );
    $response = $this->drupalGet($url);
    

    And once #2878463: [PP-1] Define a JSON API link relation for entities lands:

    $url = $this->referencingEntity->toUrl('jsonapi')->setOption('query', ['include' => ['field_internal']]);
    $response = $this->drupalGet($url);878463] lands, it could just become:
    
gabesullice’s picture

Status: Needs work » Needs review
StatusFileSize
new6.24 KB
new4.57 KB

Can't wait for #31.8, that will be great.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/tests/modules/jsonapi_entity_test/src/Entity/EntityTestNoLabel.php
@@ -22,6 +22,9 @@ use Drupal\entity_test\Entity\EntityTest;
+ * @todo remove this class when this lands: https://www.drupal.org/project/drupal/issues/2943209

… and when JSON API requires a core version that contains it. That can be fixed on commit.

This patch does come with proper test coverage (that's in fact the majority of this patch!), and does it in the way that @e0ipso indicated he prefers in #24. RTBC :)

wim leers’s picture

Status: Reviewed & tested by the community » Fixed
StatusFileSize
new842 bytes

  • Wim Leers committed cea8ddc on 8.x-1.x authored by gabesullice
    Revert "Issue #2939705 by gabesullice, Wim Leers, e0ipso: Do not include...
wim leers’s picture

Status: Fixed » Needs work

This broke JSON API on Drupal 8.6: https://www.drupal.org/pift-ci-job/884832.

1) Drupal\Tests\jsonapi\Functional\InternalEntitiesTest::testIncludes
PHPUnit_Framework_Exception: Argument #2 (No Value) of PHPUnit_Framework_Assert::assertArrayNotHasKey() must be a array or ArrayAccess

/var/www/html/modules/contrib/jsonapi/tests/src/Functional/InternalEntitiesTest.php:96

Looks like we're getting back a HTML 404 response.

Reverted.

wim leers’s picture

gabesullice’s picture

Status: Needs work » Needs review
StatusFileSize
new7.07 KB
new680 bytes

This includes the change from #35.

gabesullice’s picture

StatusFileSize
new4.7 KB
new2.87 KB

Since this was last committed, #2943209: Mark at least one entity_test entity type as 'internal' actually landed and was backported to 8.5. So it's safe to remove the JSON API placeholder :)

gabesullice’s picture

+++ a/src/Context/FieldResolver.php
@@ -263,7 +263,9 @@
+      $resource_types = array_filter(
+        $this->collectResourceTypesForReference($definition)
+      );
-      $resource_types = $this->collectResourceTypesForReference($definition);

I don't know why this is in the interdiff. It's not in the patch though.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

#40: Now that's a nice silver lining! 🎉

#40 was tested against both D8.4 and D8.6 … but before #2930028: Comprehensive JSON API integration test coverage phase 1: for every entity type, individual resources only was committed. Let's retest to make sure it still passes against both core branches.

If that comes back green, I'll commit this.

wim leers’s picture

Status: Reviewed & tested by the community » Fixed

Both came back green! Committed!

Status: Fixed » Closed (fixed)

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