Closed (fixed)
Project:
JSON:API
Version:
8.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
25 Jul 2017 at 14:07 UTC
Updated:
2 Jul 2018 at 11:05 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
grimreaperComment #3
grimreaperThe problem is in jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php getAllowedResourceTypes(), The "item_definition" structure is different depending of the field type.
So currently it works only for basic entity reference fields.
I don't see how to get the types dynamically for all entity reference fields sub-class.
Maybe a temporary solution would be a switch on the field type. The field type machine name is contained in $item_definition->definition['type'] (maybe not accessible this way, it is a xdebug return that I copy pasted in the issue) field_item:dynamic_entity_reference
Or creating an eventdispatcher to get to be able to register other entity reference types.
Comment #4
e0ipso@Grimreaper, would you be kind enough to check if this issue is still relevant? If not, please feel free to close it.
Comment #5
grimreaper@e0ipso, thanks for the reply. But it still does not work.
I use the config from http://cgit.drupalcode.org/entity_share/tree/modules/entity_share_server...
I do not have jsonapi_files or file_entity enabled.
I retried for a relationship on a taxonomy term: OK
POST on http://entity-share.lxc/jsonapi/node/ess_test/178d4419-457e-40be-9f24-20...
Where 178d4419-457e-40be-9f24-20e2045e397e is the UUID of an ess_test node with only a title.
Authorization: basic auth using the admin user
Headers: Content-Type:application/vnd.api+json
Body (raw):
Where dfb649ce-d4ca-4bc0-b3f0-f56e8c525912 is the UUID of a pre-created taxonomy term.
Request OK.
Now with an image file with the file already created through the upload on another content.
POST on http://entity-share.lxc/jsonapi/node/ess_test/178d4419-457e-40be-9f24-20...
Authorization: basic auth using the admin user
Headers: Content-Type:application/vnd.api+json
Body (raw):
where 7c60643f-34b0-4670-a0a3-7d63aa280132 is the UUID of the file entity created by upload on another content.
The result is the HTML a Drupal error page:
And the status is 422 Unprocessable Entity.
Comment #6
wim leersComment #7
grimreaperHello,
And here is a failing test.
Comment #9
wim leersYay, a failing test, thank you! 👏
The failure says it's a 422 instead of a 201 response. If I print the exact error response:
… then I see:
In other words: the entity you're trying to reference is not accessible to you. That error is generated by
\Drupal\Core\Entity\Plugin\Validation\Constraint\ReferenceAccessConstraint+\Drupal\Core\Entity\Plugin\Validation\Constraint\ReferenceAccessConstraintValidator.I did some debugging and … the reason this test is failing is:
because
\Drupal\file\FileAccessControlHandler::checkAccess()only grantsviewaccess topublic://files. Updated the test to use that, and now it should be green.So I'm going to bet that you're test with a
private://file.Comment #11
wim leers#9 now fails in
testRead()because the expected normalization is now different. But it now does passtestWrite().Needs confirmation from @Grimreaper that he's using
private://.Comment #12
wim leers#2899109: Trouble PATCHing a File Field might be a duplicate of this.
Comment #13
grimreaperHello,
Thanks @Wil Leers for the debug.
Unfortunately no, I was testing on a public:// image field before testing on private://
Comment #14
wim leers#13: ok then this definitely at minimum, and ideally (because then we don't need manual steps to reproduce anymore).
Comment #15
wim leers#2932031: Comprehensive JSON API integration test coverage phase 2: for every entity type, complex use-cases added
\Drupal\Tests\jsonapi\Functional\MediaTest. Updating its\Drupal\Tests\jsonapi\Functional\MediaTest::getPostDocument()would be sufficient to add test coverage for this!Comment #16
wim leersComment #17
wim leersNo movement, so I'm doing it for you. Passes tests just fine, so either this was indeed a permission problem as I said before, or JSON API fixed this in the mean time.
Ideally, this would have the client upload a file via a HTTP API. Support for that landed only days ago in Drupal core's REST module. Created #2958554: Allow creation of file entities from binary data via JSON API requests to port it to JSON API.
For now, this test can just have PHP create a
Fileentity, just to test that referencingFileentities works.(No interdiff, because new patch.)
Comment #18
wim leersSadly, #17 fails due to a subtle difference in normalization. Not sure where/why/how this is happening, we need to dig into that.
Comment #19
wim leersComment #22
wim leersLet's get this going again.
Comment #23
wim leersThe interdiff in #18 is completely wrong. Correct interdiff attached.
It's strange that #18 did not pass, because it passes locally for me, at least today. Maybe other changes in the past month made a difference.
Attached is also a rebased #18, which passes for me locally, on D8.6.
Comment #25
wim leersInteresting! That failed. Let's see if the same happens on 8.6. Queued an 8.6 test.
Comment #26
wim leersD'oh 😅
Comment #27
wim leersYay, green! We can't commit it just yet though, because:
This is that subtle difference in normalization that #18 referred to. Digging in…
Comment #28
wim leersLocally, this seems to pass just fine now. Let's see if DrupalCI agrees with that.I was stupidly testing
MediaTest::testGetIndividual()instead ofMediaTest::testPostIndividual()😳Comment #30
wim leersTurns out the root cause is quite mundane: Entity/Field API. When it loads entities from the database, all field values of the in-memory
EntityInterfaceobject are strings! This is AFAIK even accepted as normal (even though it certainly is annoying).The correct solution would be to make property normalization respect the underlying type, i.e. to do the appropriate casting. Even though Entity/Field API really should've taken care of that for us. So let's do that!
So I did.
And in doing so, found that several of HEAD's assertions also had incorrect values due to the same root cause, and those now are correct too! 🤘
Comment #31
wim leersI think it's clear we've disproven the original bug report. Let's make this a task to add test coverage that proves this is possible. And to ensure we don't ever regress!
Comment #32
wim leersIndentation is off.
PATCHtest coverage that also does this string casting business … and I think it may be possible to remove that now!(At which point
\Drupal\Tests\jsonapi\Functional\ResourceTestBase::castToString()can be removed too, because zero callers remain!)Comment #33
gabesulliceDo we need to be doing this type casting elsewhere too? Like
FieldItemNormalizer? Perhaps it's only needed here because we're special casing entity reference?In
FieldItemNormalizer, we pass field item properties into the serialization system:I've always wondered when/where this method would actually come in handy. TIL.
Can we add a comment explaining the new permission?
Nit: Is there a way to make these integers dynamic or make then a static property?
This is satisfying.
😍
Comment #34
gabesulliceI realized my review in #32 doesn't actually have any points that need work. It's mostly questions and suggestions, so it shouldn't technically be "Needs Work", but there's not a better status.
Comment #35
wim leers#33:
Thanks for the review!
description: null(instead ofdescription: '') anddisplay: null(instead ofdisplay: false) return… But fixing that is arguably out of scope.Also fixed the CS violation.
Comment #36
gabesulliceComment #38
wim leers🍻
Comment #40
grimreaperHi,
Sorry for the delay, I just want to say thank you to all for your work on that.