Discovered while working on #2930028: Comprehensive JSON API integration test coverage phase 1: for every entity type, individual resources only.

From #2930028-9: Comprehensive JSON API integration test coverage phase 1: for every entity type, individual resources only's test results:

--- Expected
+++ Actual
@@ @@
-{"errors":[{"title":"Unprocessable Entity","status":422,"detail":"Unprocessable Entity: validation failed.\ntitle: Title: this field cannot hold more than 1 values.\n","links":{"info":"http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html"},"code":0}]}
+{"errors":[{"title":"Unprocessable Entity","status":422,"detail":"There was an error un-serializing the data. Message: Deserialization for the format  is not supported","links":{"info":"http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html"},"code":0}]}

Plus, the following test assertions had to be commented:

    // DX: 415 when no Content-Type request header. HTML response because
    // missing ?_format query string.
    $response = $this->request('POST', $url, $request_options);
    $this->assertSame(415, $response->getStatusCode());
    $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type'));
    $this->assertContains('A client error happened', (string) $response->getBody());

    $url->setOption('query', ['_format' => 'api_json']);

    // DX: 415 when no Content-Type request header.
    $response = $this->request('POST', $url, $request_options);
    $this->assertResourceErrorResponse(415, 'Unsupported Media Type', 'No "Content-Type" request header specified', $response);

Comments

Wim Leers created an issue. See original summary.

wim leers’s picture

Status: Active » Needs review
StatusFileSize
new1.84 KB
wim leers’s picture

GuzzleHttp\Exception\ClientException: Client error: `HEAD http://php-apache-jenkins-drupal8-contrib-patches-19317/subdirectory/jsonapi/node/article` resulted in a `415 Unsupported Media Type` response

Oh FFS, this is a bug in Drupal core.

wim leers’s picture

wim leers’s picture

Created an issue for Drupal core, plus test coverage: #2934152: ContentTypeHeaderMatcher should not run for GET, HEAD, OPTIONS or TRACE requests. Please review+RTBC!

wim leers’s picture

wim leers’s picture

StatusFileSize
new1.11 KB
new2.94 KB

Funny, so for now the correct bugfix doesn't work due to a core bug 😩

The reason core doesn't run into this bug: because the REST module doesn't have a single route for reading *and* writing.

wim leers’s picture

Title: JSON API routes not specifying _content_type_format route requirement, resulting in bad DX » [PP-1] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX
Status: Needs review » Postponed

#7 comments the existing test, but that's no solution either, because the new coverage being added in #2930028: Comprehensive JSON API integration test coverage phase 1: for every entity type, individual resources only also contains HEAD requests, and so will run into the same failure.

:/ :/ :/

wim leers’s picture

Title: [PP-1] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX » JSON API routes not specifying _content_type_format route requirement, resulting in bad DX

Wow, #2934152: ContentTypeHeaderMatcher should not run for GET, HEAD, OPTIONS or TRACE requests already landed, but only in 8.5. I think it should also be able to land in 8.4. But even then JSON API wouldn't be able to commit+release this until a 8.4 patch release is tagged that contains it.

Well, in any case, the necessary bugfix does exist in 8.5, so this will definitely get fixed now :)

e0ipso’s picture

Should we merge this one and it will work for people running 8.5? Or what approach do you want to take?

wim leers’s picture

Should we merge this one and it will work for people running 8.5? Or what approach do you want to take?

We should wait to commit+release this at least until 8.5.0 is released.

If we commit this now, HEAD requests will fail when you're running Drupal <8.5. To be fair, until #2933515: JSON API does not support HEAD requests, HEAD requests didn't work in JSON API at all. So… maybe you don't mind committing this as-is, but that does imply that you're accepting that HEAD requests will never work in 8.4!

That's why I think it's probably better to wait until at least 8.5 is out, and quite possibly we should only commit this when JSON API requires >=8.5.

e0ipso’s picture

Issue tags: -blocker +waits for 8.4 unsupported

I wish d.o had a minor release alarm system.

Removing the blocker tag.

wim leers’s picture

#12: maybe some day in the future :) Every minor release gets better and better at signaling things to contrib! For example, the use of @trigger_error(…, E_USER_DEPRECATED), and the testing infrastructure around that.

wim leers’s picture

Title: JSON API routes not specifying _content_type_format route requirement, resulting in bad DX » [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX
wim leers’s picture

wim leers’s picture

Version: 8.x-1.x-dev » 8.x-2.x-dev
wim leers’s picture

Status: Postponed » Needs review
Issue tags: -waits for 8.4 unsupported
StatusFileSize
new2.77 KB

Rebased #7.

wim leers’s picture

StatusFileSize
new1.11 KB
new1.67 KB

#2934152: ContentTypeHeaderMatcher should not run for GET, HEAD, OPTIONS or TRACE requests already landed in 8.5, so we can actually revert the test changes that were necessary to make this pass tests.

wim leers’s picture

StatusFileSize
new1.96 KB
new3.62 KB

And if all is well, then we should now be able to restore commented out test coverage that this patch fixes.

wim leers’s picture

Title: [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX » [PP-1] [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX
Status: Needs review » Postponed

#19 has one new fail:

1) Drupal\Tests\jsonapi\Functional\JsonApiFunctionalTest::testWrite
Failed asserting that 415 matches expected 204.

/var/www/html/core/tests/Drupal/Tests/BrowserTestBase.php:1287
/var/www/html/modules/contrib/jsonapi/tests/src/Functional/JsonApiFunctionalTest.php:843

The improvements we made to ContentTypeHeaderMatcher in #2934152: ContentTypeHeaderMatcher should not run for GET, HEAD, OPTIONS or TRACE requests were correct … but apparently we didn't think to also do the DELETE case. DELETE requests never have a request body. And so it doesn't make sense to require a Content-Type request header either.

So we'll need to fix that in ContentTypeHeaderMatcher too. Created #2971012: ContentTypeHeaderMatcher should not run for DELETE requests for that.

wim leers’s picture

#2971012: ContentTypeHeaderMatcher should not run for DELETE requests now has a patch, with test coverage, that will hopefully land soon.

wim leers’s picture

StatusFileSize
new3.48 KB
new7.05 KB

More importantly, all those other failures (which you already see in #17 and #18) look like this:

2) Drupal\Tests\jsonapi\Functional\TermTest::testPostIndividual
Failed asserting that 415 is identical to 400.

/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:533
/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:650
/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:1271

3) Drupal\Tests\jsonapi\Functional\TermTest::testPatchIndividual
Failed asserting that 415 is identical to 400.

/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:533
/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:650
/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:1539

4) Drupal\Tests\jsonapi\Functional\TermTest::testDeleteIndividual
Failed asserting that 415 is identical to 403.

/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:533
/var/www/html/modules/contrib/jsonapi/tests/src/Functional/ResourceTestBase.php:1824

Those are happening because with this patch, a 415 response will occur whenever no Content-Type header is specified, so some of the pre-existing test coverage needs to be updated: it needs some commented test coverage uncommented.

wim leers’s picture

StatusFileSize
new3.48 KB

d.o-- (d.o messed up the interdiff)

Here's the right interdiff.

wim leers’s picture

Title: [PP-1] [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX » [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX
Status: Postponed » Needs work

Holy shit, #2971012: ContentTypeHeaderMatcher should not run for DELETE requests already got committed! 🙀

Back to Needs Work now…

wim leers’s picture

Status: Needs work » Needs review
StatusFileSize
new7.05 KB

Actually, no, just re-testing the patch should fix most of the failures! #22 has 12 fails. Reuploading the same patch, now should have fewer fails.

wim leers’s picture

StatusFileSize
new3.76 KB
new10.82 KB

And fixing some minor bugs in some tests should make the patch green!

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

Bam!

The last submitted patch, 7: 2934149-7.patch, failed testing. View results

gabesullice’s picture

Status: Needs review » Reviewed & tested by the community

+1, I don't think this issue ever technically had a review, it just had a lot of back and forth. It does look good to me though :) nice DX improvement.

wim leers’s picture

I didn't mind self-RTBC'ing because it's really just a pure bug fix release. This change is necessary to use the D8 request processing/routing system correctly. The test coverage was inherited from core's REST module, which underwent as much scrutiny as one could ask for, and had to be commented due to this oversight/bug.

Still, great to have your confirmation :)

wim leers’s picture

StatusFileSize
new10.51 KB

#2943170: JSON API's RequestHandler causes fatal PHP error when a PATCH or POST request has no body was committed, this needed a significant rebase. Nice consequence: the diff is now much easier to understand :)

wim leers’s picture

StatusFileSize
new10.68 KB

Conflicted with #2971562: Refactor/clean-up Routes.php in Routes.php. Rebased.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 32: 2934149-32.patch, failed testing. View results

  • gabesullice committed a3ca2f0 on 8.x-2.x
    Issue #2934149 by Wim Leers, gabesullice: [>=8.5] JSON API routes not...
gabesullice’s picture

Status: Needs work » Fixed
StatusFileSize
new8.94 KB

I didn't realize you had posted a different patch, I simply applied a rerolled version of #31. It's a bit different from yours. Attached the full patch.

gabesullice’s picture

StatusFileSize
new1023 bytes

The above patch broke relationship tests in HEAD. This is a case of bad tests not logic at least :) It does prove why this needed to be a 2.x change.

  • gabesullice committed 0cc3bb2 on 8.x-2.x
    Issue #2934149 followup by gabesullice: relationship tests should assert...
wim leers’s picture

Status: Fixed » Reviewed & tested by the community
StatusFileSize
new1.11 KB

There was one bit of commented test coverage that I failed to uncomment.

  • Wim Leers committed ea41e77 on 8.x-2.x
    Issue #2934149 follow-up by Wim Leers: [>=8.5] JSON API routes not...
wim leers’s picture

Status: Reviewed & tested by the community » Fixed
wim leers’s picture

Status: Fixed » Closed (fixed)

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