Add validation constraints to filter.settings

Created on 20 October 2023, about 1 year ago
Updated 6 March 2024, 8 months ago

Problem/Motivation

Filter module settings has 1 property paths that are not yet validatable:

./vendor/bin/drush config:inspect --filter-keys=filter.settings --detail --list-constraints  --fields=key,validatability,constraints
➜  πŸ€– Analyzing…

 ---------------------------------------------- ------------- ------------------------------------------ 
  Key                                            Validatable   Validation constraints                    
 ---------------------------------------------- ------------- ------------------------------------------ 
  filter.settings                                80%           ValidKeys: '<infer>'                      
                                                               RequiredKeys: '<infer>'                   
   filter.settings:                              Validatable   ValidKeys: '<infer>'                      
                                                               RequiredKeys: '<infer>'                   
   filter.settings:_core                         Validatable   ValidKeys:                                
                                                                 - default_config_hash                   
                                                               RequiredKeys: '<infer>'                   
   filter.settings:_core.default_config_hash     Validatable   NotNull: {  }                             
                                                               Regex: '/^[a-zA-Z0-9\-_]+$/'              
                                                               Length: 43                                
                                                               ↣ PrimitiveType: {  }                     
   filter.settings:always_show_fallback_choice   Validatable   ↣ PrimitiveType: {  }                     
   filter.settings:fallback_format               NOT           ⚠️  @todo Add validation constraints here  
 ---------------------------------------------- ------------- ------------------------------------------ 

Steps to reproduce

  1. Get a local git clone of Drupal core 11.x.
  2. composer require drupal/config_inspector β€” or manually install https://www.drupal.org/project/config_inspector/releases/2.1.5 β†’ or newer (which supports Drupal 11!)
  3. composer require drush/drush
  4. vendor/bin/drush config:inspect --filter-keys=filter.settings --detail --list-constraints

Proposed resolution

Add validation constraints to:

  1. filter.settings:fallback_format

This requires looking at the existing code and admin UI (if any) to understand which values could be considered valid. Eventually this needs to be reviewed by the relevant subsystem maintainer.

For examples, search *.schema.yml files for the string constraints: 😊

Reach out to @borisson_ or @wimleers in the #distributions-and-recipes.

Remaining tasks

  1. filter.settings:fallback_format

User interface changes

None.

API changes

None.

Data model changes

More validation πŸš€

Release notes snippet

None.

πŸ“Œ Task
Status

Fixed

Version

11.0 πŸ”₯

Component
FilterΒ  β†’

Last updated about 2 hours ago

No maintainer
Created by

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

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @borisson_
  • πŸ‡§πŸ‡ͺBelgium borisson_ Mechelen, πŸ‡§πŸ‡ͺ
  • πŸ‡§πŸ‡ͺBelgium borisson_ Mechelen, πŸ‡§πŸ‡ͺ
  • First commit to issue fork.
  • First commit to issue fork.
  • Status changed to Needs review about 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom Eli-T Manchester
  • Merge request !5085Issue #3395562: 🦺 add new... β†’ (Open) created by Eli-T
  • last update about 1 year ago
    30,425 pass, 1 fail
  • last update about 1 year ago
    30,425 pass, 1 fail
  • Pipeline finished with Canceled
    about 1 year ago
    Total: 4s
    #35900
  • Pipeline finished with Failed
    about 1 year ago
    Total: 702s
    #35901
  • πŸ‡¬πŸ‡§United Kingdom Eli-T Manchester

    This MR introduces a new Constraint that checks that an entity with a given ID and entity type exists. This is probably useful in a number of other places so it would be worth reviewing issues that might need it and linking so we're not duplicating work

  • last update about 1 year ago
    30,425 pass, 1 fail
  • last update about 1 year ago
    30,425 pass, 1 fail
  • Pipeline finished with Failed
    about 1 year ago
    Total: 616s
    #36155
  • Status changed to Needs work about 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom Eli-T Manchester

    The assertion that is currently failing is in ConfigImportAllTest::testInstallUninstall() on line 147

        // Check that all modules that were uninstalled are now reinstalled.
        $this->assertModules(array_keys($modules_to_uninstall), TRUE);
    
  • πŸ‡¬πŸ‡§United Kingdom Eli-T Manchester

    The test is asserting that a set of modules are enabled, and is failing because block_content is not enabled. However, debugging shows it would fail on other modules - here's a list of the enabled status of all checked modules.

    action = true
    announcements_feed = true
    automated_cron = true
    ban = true
    basic_auth = true
    big_pipe = true
    block = true
    block_content = false
    book = false
    breakpoint = false
    ckeditor5 = false
    comment = false
    config_translation = false
    contact = false
    content_moderation = false
    content_translation = false
    contextual = false
    datetime = false
    datetime_range = false
    dblog = false
    dynamic_page_cache = true
    editor = false
    field = false
    field_layout = false
    field_ui = false
    file = false
    filter = true
    forum = false
    help = true
    history = false
    image = false
    inline_form_errors = true
    jsonapi = false
    language = false
    layout_builder = false
    layout_discovery = false
    link = false
    locale = false
    media = false
    media_library = false
    menu_link_content = false
    menu_ui = false
    migrate = false
    migrate_drupal = false
    migrate_drupal_ui = false
    node = false
    options = false
    page_cache = true
    path = false
    pgsql = true
    phpass = false
    responsive_image = false
    rest = false
    sdc = false
    search = false
    serialization = false
    settings_tray = false
    shortcut = false
    sqlite = true
    statistics = false
    syslog = true
    experimental_module_requirements_test = true
    experimental_module_test = true
    system_test = true
    taxonomy = false
    telephone = false
    text = false
    toolbar = false
    tour = true
    update = true
    views = false
    views_ui = false
    workflows = false
    workspaces = false
  • πŸ‡§πŸ‡ͺBelgium borisson_ Mechelen, πŸ‡§πŸ‡ͺ

    I have tried to figure out what the problem is what that testInstallUninstall, I don't understand what the problem is, there is no config errors when installing or when uninstalling, so why some modules don't want to be installed is a mystery to me.
    I don't think it is because those modules all depend on filter, because for example workspaces only depends on user.

  • πŸ‡ͺπŸ‡ΈSpain nireneko

    I checked this, and I can't find the problem, but like @borisson_ sais, must be in the config, debugging the core.extensions.yml file has the full list of modules that must be installed, but when the syncronization is executed in the test ConfigImportAllTest lines:

    $this->drupalGet('admin/config/development/configuration');
    $this->submitForm([], 'Import all');
    

    Is not installing all the modules.

    I tried to debug the syncronization import in Drupal\config\Form\ConfigSync, but I can't :(

    Getting the list of enabled modules before

    // Check that all modules that were uninstalled are now reinstalled.
        $this->assertModules(array_keys($modules_to_uninstall), TRUE);

    line, there are 26 installed modules of 74.

    Also something strange, in the new validator EntityExistsConstraintValidator, adding one "return;" before add the violation (or removing the violation), the test is green and I don't understand why, because in my case, that point never is reached, the 'if' always is 'true'.

        // If we can load an entity of the given type with the ID in value we pass
        // the constraint.
        if ($this->entityTypeManager->getStorage($constraint->entityType)->load($value)) {
          return;
        }
    
        return;
    
        $violation = $this->context
          ->buildViolation($constraint->message)
          ->setParameter('@entity_type', $constraint->entityType)
          ->setParameter('%value', $value);
        $violation->addViolation();
    
  • πŸ‡΅πŸ‡ͺPeru marvil07

    I could not find the actual problem either.
    Said that, hopefully some extra clues follow.

    Also something strange, in the new validator EntityExistsConstraintValidator, adding one "return;" before add the violation (or removing the violation), the test is green and I don't understand why, because in my case, that point never is reached, the 'if' always is 'true'.

    @nireneko, that is expected, a return or the non-creation of a violation means the constraint passes validation.

    As stated at previous comments, there are multiple modules not enabled on the configuration import done on the failing test.

    Finding the error is a bit tricky, since ConfigImportAllTest::testInstallUninstall() is using the configuration synchronization UI, and that uses the batch API.
    Inside the Batch API, errors seem to not be relied, or at least not in tests, see ob_\* calls at https://git.drupalcode.org/project/drupal/-/blob/0bbf07394de4a370c28b904....

    Trying to figure the problem out, I noticed that if the module installer service is used to enable the modules, they can be enabled.
    E.g. adding the following change will make block_content module enabled correctly, and the error will be reported on the next not re-enabled module, book.

    diff --git a/core/modules/config/tests/src/Functional/ConfigImportAllTest.php b/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
    index 4d693c6333..7beb8b66ea 100644
    --- a/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
    +++ b/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
    @@ -139,6 +139,7 @@ public function testInstallUninstall() {
         $this->submitForm([], 'Import all');
         // Modules have been installed that have services.
         $this->rebuildContainer();
    +    $this->assertTrue(\Drupal::service('module_installer')->install(['block_content']), 'Manually installing block_content actually installs it.');
     
         // Check that there are no errors.
         $this->assertSame([], $this->configImporter()->getErrors());
    

    In other words, the code path enabling the modules with the configuration synchronization form on the test is doing something different than the call to \Drupal::service('module_installer')->install().
    What exactly, not quite sure.

    Overall, it may be that the new configuration validation is correctly triggering a problem, but that problem seems to only exist on the testing code path, and not on the normal code path, outside test via phpunit.

  • πŸ‡·πŸ‡΄Romania claudiu.cristea Arad πŸ‡·πŸ‡΄

    I find something weird with schema of filters.

    This is text format schema (removed some parts for readability):

    filter.format.*:
      type: config_entity
      mapping:
        name:
          type: required_label
        (...)
        filters:
          type: sequence
          orderby: key
          sequence:
            type: filter
    

    Each filter is of type filter:

    filter:
      type: mapping
      mapping:
        id:
          type: string
        (...)
        settings:
          type: filter_settings.[%parent.id]
    

    Each filter's settings is of type `filter_settings.`, defaulting to `filter_settings.*`

    But here comes the weirdness: Each `filter_settings.` is again of type filter (except filter_settings.* which correctly goes to a sequence.

    For instance:

    filter_settings.filter_html:
      type: filter
      mapping:
        ...
    

    I think each `filter_settings.` should be of type mapping

    Am I missing something?

  • πŸ‡·πŸ‡΄Romania claudiu.cristea Arad πŸ‡·πŸ‡΄

    I've opened πŸ› Filter settings schema types are incorrect Active for #14

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Blocked on πŸ› Filter settings schema types are incorrect Active .

  • Assigned to wim leers
  • Status changed to Postponed 9 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Status changed to Needs work 9 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Pipeline finished with Failed
    9 months ago
    Total: 543s
    #88050
  • Issue was unassigned.
  • Status changed to Needs review 9 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Lifted some code from ✨ [PP-1] Mark parts of CKEditor 5 and Editor config schema as fully validatable Postponed to expand what the existing ConfigExists constraint can do, which is why I associated this change record β†’ with this issue.

    It also means I was able to remove the new EntityExists constraint that @Eli-T proposed. I think that would be an excellent addition, but such a useful general addition is not a hard blocker for this issue. There's now two distinct issues that would benefit from that expansion in capability for ConfigExists, so went ahead with that.

    What's still missing is test coverage. \Drupal\Tests\filter\Functional\FilterAdminTest::testFilterAdmin() does some testing of filter.settings, so is the closest place we have.

  • Pipeline finished with Failed
    9 months ago
    Total: 587s
    #88057
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Aha … the reason Drupal.Tests.config.Functional.ConfigImportAllTest is not passing tests is actually quite simple:

    1. filter.settings is simple config
    2. ⚠️ Only config entities are allowed to have config dependencies
    3. When filter.settings is installed/saved, text format config entities have not yet been installed
    4. Hence ConfigImportAllTest::testInstallUninstall() fails.

    There is the short-term solution and the long-term one:

    Because there is no clear long-term solution either, I think the short-term solution is fine for now.

  • Pipeline finished with Canceled
    9 months ago
    Total: 406s
    #88063
  • Pipeline finished with Success
    9 months ago
    Total: 566s
    #88068
  • Status changed to Needs work 9 months ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Left a small comment, let me know what you think.

  • Status changed to RTBC 9 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    This flaw in filter.settings was introduced in #1799440: Convert Filter variables to Configuration System β†’ .

    #1932544: Remove all traces of fallback format concept from the (admin) UI β†’ is the long-term solution.

    Updated comment πŸ‘

  • Pipeline finished with Success
    9 months ago
    Total: 601s
    #91346
    • catch β†’ committed d5580c8d on 11.x
      Issue #3395562 by Wim Leers, Eli-T, borisson_, nireneko, claudiu.cristea...
  • Status changed to Fixed 9 months ago
  • πŸ‡¬πŸ‡§United Kingdom catch

    Committed/pushed to 11.x, thanks!

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024