Problem/Motivation

While triaging #2703713: core link field and token, @larowlan, @xjm, @pameeela and I agreed that we are missing some test coverage for the link field.

For example cases like:

http://www.example.com/?name=ferret&color=purple
http://www.example.com/page?name=ferret&color=purple
http://www.example.com?a=&b[]=c&d[]=e&d[]=f&h==

and

/page?name=ferret&color=purple
/page?a=&b[]=c&d[]=e&d[]=f&h==

Proposed resolution

Add more test coverage as KTB.

Remaining tasks

Create a patch.

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

N/A

Comments

jibran created an issue. See original summary.

larowlan credited pameeela.

larowlan credited xjm.

larowlan’s picture

Adding issue credit for folks who spent 20+ mins triaging the related issue in the OP

jibran’s picture

Crediting @larowlan, @xjm, @pameeela, and I here for identifying the issue with the test coverage.

quietone’s picture

Status: Active » Needs review
StatusFileSize
new1.64 KB

Are there any other test cases that should be added?

quietone’s picture

StatusFileSize
new6.33 KB
new6.87 KB

Did some searching and found a list of valid and invalid URLs and added those to the list. This assumes that list is correct (I haven't read the relevant RFC). There may be some duplication with existing tests which I didn't catch. I found it a bit of an eye strain to compare the new ones with the existing ones.

The valid URLs pass tests but some of the invalid ones don't. I did manual testing to determine that these invalid ones are accepted in the link field.

The following invalid URLs are accepted.

http://.
http://..
http://../
http://foo.bar?q=Spaces should be encoded
//a
foo.com
http:// shouldfail.com
http://foo.bar/foo(bar)baz quux
http://-error-.invalid/
http://-a.b.co
http://a.b-.co
http://0.0.0.0
http://3628126748
http://.www.foo.bar/
http://www.foo.bar./
http://.www.foo.bar./

Status: Needs review » Needs work

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

jibran’s picture

Intersting seems like we are missing some coverage for \Drupal\Core\Url::fromUri()(\Drupal\link\Plugin\Validation\Constraint\LinkTypeConstraintValidator::validate() calls \Drupal\link\Plugin\Field\FieldType\LinkItem::getUrl() which calls \Drupal\Core\Url::fromUri()) as well then.

http://.
http://..
http://../
http://foo.bar?q=Spaces should be encoded
//a
foo.com
http:// shouldfail.com
http://foo.bar/foo(bar)baz quux
http://-error-.invalid/
http://-a.b.co
http://a.b-.co
http://0.0.0.0
http://3628126748
http://.www.foo.bar/
http://www.foo.bar./
http://.www.foo.bar./

Drupal use parse_url to validate URLs and these doesn't returnFALSE.
e.g:

# php -r "print_r(parse_url('http://.'));"
Array
(
    [scheme] => http
    [host] => .
)
# php -r "print_r(parse_url('http://..'));"
Array
(
    [scheme] => http
    [host] => ..
)
# php -r "print_r(parse_url('//a'));"
Array
(
    [host] => a
)
quietone’s picture

I've taken a look at each of those issues, which all have patches. The solution I like best is 2652236-comment #34 where Charlie ChX Negyesi posts a custom solution that uses the the Symfony Url validator. I prefer that instead of re-inventing the wheel.

So, here we could keep in scope and remove failing tests. Well, instead of removing how about adding in a todo block with a reference to a followup. That followup could be one of the existing issues or a new one to discuss using Symfony Url validator.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new2.66 KB
new5.94 KB

Getting this back in scope. This patch removes the false positives from the list of invalid URLs added in #7. That leaves a patch that only adds more test coverage to the LinkWidget. Fixing/Improving the validation will happen in one of the other issues.

Status: Needs review » Needs work

The last submitted patch, 12: 3151047-12.patch, failed testing. View results

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new543 bytes
new5.89 KB

Missed one.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Patch looks OK now. Let's triage the other issues and mark some of them duplicates if we can so that we can fix the actual bugs as well.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: -Novice

One concern I have here is that this is a functional test, so we're adding quite a lot of overhead/execution time to our tests by adding all of these cases, as each one of them does an extra 2 HTTP requests.

So the question is, can we test this using a kernel test - the validate method is static and public, so in theory yes.

Removing the Novice tag, because refactoring to a kernel test is an advanced topic.

jibran’s picture

Status: Needs review » Needs work

@larowlan good idea but we can't move all because we still want to test \Drupal\link\Plugin\Field\FieldWidget\LinkWidget::validateUriElement using functional test. We can move others which are failing because of constraints = {"LinkType" = {}, "LinkAccess" = {}, "LinkExternalProtocols" = {}, "LinkNotExistingInternal" = {}}. I think we should update \Drupal\Tests\link\Kernel\LinkItemTest to accommodate those cases.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new4.95 KB

Alright another try here. This just adds a kernel and does not change the functional tests. The Functional test already includes a test for the error message from validateUriElement and results from 3 of the 4 constraints. I don't see a test for "LinkNotExistingInternal", but I could be wrong.

No interdiff because this removes all previous changes and adds a new test.

larowlan’s picture

  1. +++ b/core/modules/link/tests/src/Kernel/LinkItemUrlValidationTest.php
    @@ -0,0 +1,121 @@
    +  public function testExternalLinkValidation() {
    

    🤩 amazing work.

  2. +++ b/core/modules/link/tests/src/Kernel/LinkItemUrlValidationTest.php
    @@ -0,0 +1,121 @@
    +    $test_links = $this->getTestLinks();
    

    At first I was going to suggest this could use a dataProvider but then we're paying the install cost for each test-case, so I think it is better as it stands

  3. +++ b/core/modules/link/tests/src/Kernel/LinkItemUrlValidationTest.php
    @@ -0,0 +1,121 @@
    +      $link_item->setValue($data[0]);
    ...
    +      $expected_count = count($data[1]);
    

    we could use list($value, $violations) = $data
    to make this a bit more readable than $data[0] and $data[1]

  4. +++ b/core/modules/link/tests/src/Kernel/LinkItemUrlValidationTest.php
    @@ -0,0 +1,121 @@
    +  public function getTestLinks() {
    

    This can be protected

quietone’s picture

StatusFileSize
new1.92 KB
new5.02 KB

thanks for the review.

1. Thank you, I have had good teachers!
2. I meant to leave a comment explaining why I did that, sorry. It was just too slow as a dataprovider.
3. Fixed.
4. Fixed

And fixed the order of the parameters in $this->assertEquals so the expected value is the first parameter.

jibran’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

#16 is addressed so back to RTBC.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/link/tests/src/Kernel/LinkItemUrlValidationTest.php
@@ -0,0 +1,122 @@
+      [$value, $expected_violations] = $data;

This keeps us on 9.x only here - which I guess is ok. (Array de-structuring is not supported in php 7.0)

+++ b/core/modules/link/tests/src/Kernel/LinkItemUrlValidationTest.php
@@ -0,0 +1,122 @@
+      ["rdar://1234", [$violation_0]],

I went to commit this, but unfortunately, this is failing with a spelling error.

perhaps we should make it radar?

Moving to needs review for ^

that passes the spelling check - but would it change the functionality of the test? I don't think so

quietone’s picture

StatusFileSize
new704 bytes
new5.02 KB

I agree that 'radar' doesn't change the functionality of the test. Patch updated.

@larowlan, apologies for the inconvenience. Looks like today I will getting cspell up and running.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, for the fix @quietone. Back to RTBC as feedback is addressed.

  • larowlan committed e2fc217 on 9.1.x
    Issue #3151047 by quietone, jibran, larowlan, xjm, pameeela: Expand...

  • larowlan committed 3944cbb on 9.0.x
    Issue #3151047 by quietone, jibran, larowlan, xjm, pameeela: Expand...
larowlan’s picture

Version: 9.1.x-dev » 9.0.x-dev
Status: Reviewed & tested by the community » Fixed

Committed e2fc217 and pushed to 9.1.x. Thanks!

Backported this to 9.0.x for consistency and because the risk of disruption is low.

Held off backporting to 8.9.x because it uses PHP 7.1+ array destructuring syntax.

Thanks everyone, this was a great demonstration of the collaborative feel of the Bug Smash Initiative at work.

Status: Fixed » Closed (fixed)

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