When setting `NotNull` constraint on type: required_label, two validation errors appear

Created on 24 November 2023, 10 months ago
Updated 6 December 2023, 9 months ago

Problem/Motivation

Ran into this while working on πŸ“Œ Configuration schema & required values: add test coverage for `nullable: true` validation support Fixed .

πŸ“Œ New config schema data type: `required_label` Fixed introduced type: required_label, and it looks like this:

required_label:
  type: label
  label: 'Label'
  constraints:
    NotBlank: {}

NotBlank has a $allowNull option that defaults to FALSE. In other words: it disallows both NULL and the empty string ''.

Unfortunately, this means that any config property that is explicitly marked required by setting the NotNull constraint, this triggers a double error:

Steps to reproduce

See tests.

Proposed resolution

  1. Write tests.
  2. β€” per @alexpott and @longwave in #16 and #19: automatically detect when both NotNull and NotBlank are present and if so, set NotBlank's allowNull: true option.

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

N/A

πŸ› Bug report
Status

Fixed

Version

11.0 πŸ”₯

Component
ConfigurationΒ  β†’

Last updated 1 day ago

Created by

πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Live updates comments and jobs are added and updated live.
  • Usability

    Makes Drupal easier to use. Preferred over UX, D7UX, etc.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @Wim Leers
  • Merge request !5543Resolve #3404061 "Required label notnull" β†’ (Open) created by Wim Leers
  • Issue was unassigned.
  • Status changed to Needs review 10 months ago
  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Assigned to Wim Leers
  • Status changed to Needs work 10 months ago
  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • First commit to issue fork.
  • Issue was unassigned.
  • Status changed to Needs review 10 months ago
  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Status changed to RTBC 10 months ago
  • πŸ‡§πŸ‡ͺBelgium borisson_ Mechelen, πŸ‡§πŸ‡ͺ

    Looks great, we have sufficient coverage and this is a small bugfix.

  • Status changed to Needs review 9 months ago
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    One of the kernel tests is failing do to this change... see https://git.drupalcode.org/issue/drupal-3404061/-/pipelines/56281/test_r...

  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Forgot to update that one. Green again πŸ‘

  • Status changed to RTBC 9 months ago
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Reran the failing javascript test and it passed so it was random.

    1) Drupal\KernelTests\Config\TypedConfigTest::testSimpleConfigValidation
    Failed asserting that two strings are equal.
    --- Expected
    +++ Actual
    @@ @@
    -'This value should not be null.'
    +'This value should not be blank.'
    /builds/issue/drupal-3404061/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqual.php:94
    /builds/issue/drupal-3404061/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php:174
    /builds/issue/drupal-3404061/vendor/phpunit/phpunit/src/Framework/TestResult.php:728
    FAILURES!
    Tests: 2, Assertions: 47, Failures: 1.
    

    Ran the test-only feature and got this so test coverage is there.

    Crediting @phenaproxima for the MR review but his name wasn't appearing on the ticket.

    Seems all feedback has been addressed though.

  • πŸ‡§πŸ‡ͺBelgium borisson_ Mechelen, πŸ‡§πŸ‡ͺ

    Agreeing with @smustgrave, all feedback has been addressed, and this is a good improvement.

  • Status changed to Needs work 9 months ago
  • πŸ‡¬πŸ‡§United Kingdom longwave UK
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @longwave, @Wim Leers and I have discussed this issue at length. The discussion resulted in wanting to explore some other options, namely:

    1. Do it at a different level, for example \Drupal\Core\TypedData\Validation\TypedDataMetadata::getConstraints(), which is what the validation system always calls β€” and detect presence of both and configure the other one correctly
    2. Override NotBlankValidator and just make allowNull: true do nothing.
    3. Look into \Symfony\Component\Validator\Constraints\Sequentially
    4. Change getDefaultConstraints() to configured NotBlank correctly instead of adding NotNull when $definition->isRequired() and NotBlank is present already.

  • Status changed to Needs review 9 months ago
  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    πŸ‘ Thanks, @alexpott!

    Just pushed an implementation of option 1.

  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    I just tried implementing Sequentially.

    Looks like my fear was unfounded: the "unpredictable ripple effects" did not happen, thanks to \Drupal\Core\TypedData\Validation\RecursiveContextualValidator::validate() being very narrow in what it accepts:

      public function validate($data, $constraints = NULL, $groups = NULL, $is_root_call = TRUE): static {
        if (isset($groups)) {
          throw new \LogicException('Passing custom groups is not supported.');
        }
    
        if (!$data instanceof TypedDataInterface) {
          throw new \InvalidArgumentException('The passed value must be a typed data object.');
        }
    

    … because \Symfony\Component\Validator\Constraints\SequentiallyValidator::validate() calls Drupal's RecursiveContextualValidator::validate() (the first ~10 lines of which are displayed above), and $data === 'en' at this point (for the langcode), it throws the exception with the The passed value must be a typed data object. message.

    IOW: to adopt Symfony's Sequentially, we need to revise a lot about how Drupal uses the symfony/validator component. For πŸ› Entity + Field + Property validation constraints are processed in the incorrect order Needs work we probably will need validation groups, which as you can see above are also explicitly not supported.

  • Assigned to Wim Leers
  • Status changed to Needs work 9 months ago
  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    alexpott 32 minutes ago
    I think option 4 is better than option 1.

    alexpott 31 minutes ago
    I think we should be doing as little as possible as changing you constraints is quite surprising.

    Will figure out how to make that work 😊

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Re #18 - I think we'd need our own Sequentially.

  • Issue was unassigned.
  • Status changed to Needs review 9 months ago
  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Implemented option 4.

    Due to

      public function getConstraints() {
        $constraints = $this->definition['constraints'] ?? [];
        $constraints += $this->getTypedDataManager()->getDefaultConstraints($this);
    …
    

    any change I make in getDefaultConstraints() gets overwritten automatically.

    So this change must happen in the quoted code (\Drupal\Core\TypedData\DataDefinition::getConstraints()).

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Only one comment about a comment, but otherwise this looks right to me and I will RTBC it once my feedback is addressed in some way. :)

  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Done πŸ˜„

  • Status changed to RTBC 9 months ago
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Ship it!

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Committed 5cd249e and pushed to 11.x. Thanks!

  • Status changed to Fixed 9 months ago
    • alexpott β†’ committed 5cd249e9 on 11.x
      Issue #3404061 by Wim Leers, borisson_, alexpott, phenaproxima, longwave...
  • πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Thanks!

    This unblocked πŸ“Œ Configuration schema & required values: add test coverage for `nullable: true` validation support Fixed but also simplified #3379091 (see #3379091-25: [PP-1] Make NodeType config entities fully validatable β†’ ) as well as any future work on adding validation constraints where NotBlank is relevant! πŸ‘

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

Production build 0.71.5 2024