Out there in #2950132: Support PHPUnit 7 optionally in Drupal 8, while keeping support for ^6.5, all EntityResourceTestBase tests fail.
That is due to the following code:
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 993957eaba..5fb8d0b6eb 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -1538,8 +1538,11 @@ protected function assert406Response(ResponseInterface $response) {
else {
// This is the desired response.
$this->assertSame(406, $response->getStatusCode());
$this->stringContains('?_format=' . static::$format . '>; rel="alternate"; type="' . static::$mimeType . '"', $response->getHeader('Link'));
$this->stringContains('?_format=foobar>; rel="alternate"', $response->getHeader('Link'));
}
}
::stringContains signature in PHPUnit 7 uses scalar type hinting, and the second argument is type hinted to bool. That leads to a fatal 'cause $response->getHeader('Link')) returns an array.
However, that method expects a bool also in previous PHPUnit versions, so I am not sure what this code is really expected to do.
I was thinking that instead of ::stringContains there should really be an ::assertContains, but that also seems weird on an array.
So, what is that snippet really expected to assert?
Comments
Comment #2
wim leersIt's meant to assert that the substring in the first parameter is present in the second parameter. The second parameter used to return a string, not an array
Comment #3
mondrakeLike this then? Using
assertContainson the first element of the array.Comment #5
mondrakeLooks like
$response->getHeader('Link')sometimes return a string and sometimes an array...Comment #6
wim leersSo apparently what I said in #2 is still true, sometimes 🙃
Comment #8
mondrakeRandom fail in #5? Queued retest.
Comment #9
mondrake#5 passed.
Comment #11
mondrakeComment #12
wim leersThe need for this change is caused by https://github.com/sebastianbergmann/phpunit/commit/5113b86ce113e531b65b....
All this change does is guarantee that
stringis passed to$this->stringContains(), instead of potentiallystring[].RTBC. Thanks for doing this!
Comment #13
mondrakeThank you. If anyone can, a review of #3031539: FileFieldTestBase tests fail under PHPUnit 7 would also be appreciated (and actually is more relevant for PHPUnit 7 compatibility).
Comment #14
mondrakeActually no, this is also changing the call to
assertContainsinstead ofstringContains, which was, I think, misused.Comment #15
wim leersThat's not what the patch is doing :)
Comment #16
wim leersNW for #14/#15.
Comment #17
mondrakeOoops..
Comment #18
mondrakestringContainsis not an assertion method, it returns a PHPUnit_Framework_Constraint_StringContains matcher object, and expects the second argument to be a bool. Based on #2, we should have anassertContainsinstead.Comment #19
mondrakeComment #20
mondrakeUhm fails seem to uncover some bugs here. NW, I’ll pass here as I do not know enough about the matter at hand.
Comment #22
berdirLooks like there is sometimes no header at all and then it fails on that?
Comment #23
mondrake#22 thanks, so this maybe?
Comment #25
mondrakePer #2 and #3 then?
Comment #27
mondrakeSo the problem seems to be here: the link header is
http://php-apache-jenkins-drupal-patches-101096/subdirectory/entity/entity_view_display/node.camelids.default?_format=xml>; rel="alternate"; type="text/xml", http://php-apache-jenkins-drupal-patches-101096/subdirectory/entity/entity_view_display/node.camelids.default?_format=foobar>; rel="alternate"; type=""but expected to contain
?_format=xml>; rel="alternate"; type="text/xml; charset=UTF-8"Clearly ; charset=UTF-8 is a wrong expectation within the 'type' parameter.
Comment #28
mondrakeComment #29
mondrakeComment #30
mondrakeComment #32
mondrakePlaying whac-a-mole
Comment #34
mondrakeComment #36
mondrake#34 is getting too complicated, let's do something way simpler i.e. just split the $mimeType into the MIME type and charset, and use the MIME type only to compare against. Interdiff against #25.
Comment #37
wim leersThanks, @mondrake, #36 looks great :)
Comment #38
lendudeany way to find out when this if() triggers and add an else? Because currently we have no idea if this part of the test is EVER run, the if could be
if ($i_am_always_false)and the test would still be green.Comment #39
catchLet's answer #38
Comment #40
mondrakeI've no straight answer to #38 (not an expert), but the fact that this entire method is meant to be removed by #2805279: Routing system + authentication system + format-specific routes (e.g. those in rest.module) = frustrating, unhelpful 403 responses instead of 406 responses, see the docblock
Trying to figure out what to test in case
if ($actual_link_header) {is FALSE means getting into understanding what should be checked if there's no 'Link' header, which is probably the scope of the other issue.Here I'd suggest to keep the scope just to the replacementl of the misused
$this->stringContainscalls with the correct$this->assertContainsones. Then when #2805279: Routing system + authentication system + format-specific routes (e.g. those in rest.module) = frustrating, unhelpful 403 responses instead of 406 responses will be in, this method will be anyway removed.Setting back to RTBC, tentatively, to see if other more educated comments pop up.
Comment #41
mondrakeComment #42
krzysztof domański+1 RTBC
1.
$response->getHeader()always returns an array so$this->assertTrue(is_array($actual_link_header));is unnecessary.2. We can use
$response->hasHeader('Link').vendor\psr\http-message\src\MessageInterface.phpMy suggestions
Interdiff
Comment #43
catchCommitted b57f550 and pushed to 8.8.x. Thanks!