Problem/Motivation

Lets remove usage of "blacklist" and "whitelist" in \Drupal\Core\Template classes and their tests.

They are:

  • An historic bad labelling of people
  • Provide no context: "what is listed in them"?

Proposed resolution

  • Rename protected member variables that have "whitelisted" in their name with "allowed".
  • Deprecate settings that have "whitelisted" in their name and replace with "allowed".
  • Fix all comments accordingly

Remaining tasks

  1. Decide if we need BC. Yes. See Settings BC work from #3163226: Add the ability to deprecate a Settings name
  2. Decide if we need to touch core/lib/Drupal/Core/Template/Attribute.php too. Only 'black-cat' and 'white-cat' and friends. Seems we could leave those.
  3. Fix everything:
    • core/lib/Drupal/Core/Template/Loader/StringLoader.php - Comment only. See #3
    • core/lib/Drupal/Core/Template/TwigSandboxPolicy.php - Full of "whitelist":
        protected $whitelisted_methods;
        protected $whitelisted_prefixes;
        protected $whitelisted_classes;
      
  4. Land #3163226: Add the ability to deprecate a Settings name so we can properly deprecate the settings.
  5. Decide if/how much testing of the real settings deprecations we actually need (see #31): Decision in #38
  6. Reviews.
  7. RTBC.
  8. Decide which is the best approach:
    • #44: Magic provider that tests all real deprecated settings automatically.
    • #43: Manually defined provider for each real deprecated setting, shared test method.
    • #50: Separate test methods for each set of deprecated settings, with @expectedDeprecation annotations. No @dataProvider. Has to be replicated for each new deprecated setting.
  9. Commit appropriate patch.

User interface changes

None

API changes

None, only renaming some protected members.

Data model changes

Nope.

Release notes snippet

TBD. Probably not.

CommentFileSizeAuthor
#53 interdiff-50-53.txt690 bytesjungle
#53 3151094-53.patch7.84 KBjungle
#51 3151094-44.patch8.93 KBdww
#50 interdiff-49-50.txt1.01 KBjungle
#50 3151094-50.patch7.81 KBjungle
#49 interdiff-44-49.txt3.16 KBjungle
#49 3151094-49.patch8.56 KBjungle
#44 3151094.43_44.interdiff.txt1.94 KBdww
#44 3151094-44.patch8.93 KBdww
#43 3151094.41_43.interdiff.txt3.87 KBdww
#43 3151094-43.patch9.3 KBdww
#41 3151094.39_41.interdiff.txt1 KBdww
#41 3151094-41.patch9.49 KBdww
#39 3151094.32_39.interdiff.txt3.36 KBdww
#39 3151094-39.patch9.53 KBdww
#39 3151094-39.test-only.patch5.01 KBdww
#32 3151094.30_32.interdiff.txt4.3 KBdww
#32 3151094-32.after-3163226-no-new-tests.do-not-test.patch6.05 KBdww
#30 3151094.29_30.interdiff.txt8.16 KBdww
#30 3151094-30.with-3163226-37.only-run-SettingsTest.patch18.74 KBdww
#30 3151094-30.after-3163226.do-not-test.patch10.54 KBdww
#29 3151094.27_29.interdiff.txt1.08 KBdww
#29 3151094-29.after-3163226.do-not-test.patch8.78 KBdww
#29 3151094-29.with-3163226-21.patch14.47 KBdww
#27 3151094.22_27.interdiff.txt13.14 KBdww
#27 3151094-27.with-3163226-13.patch14.46 KBdww
#22 3151094.14_22.interdiff.txt612 bytesdww
#22 3151094-22.patch6.83 KBdww
#14 3151094.12_14.interdiff.txt2.42 KBdww
#14 3151094-14.patch6.8 KBdww
#12 3151094.6_12.interdiff.txt1.56 KBdww
#12 3151094-12.patch5.32 KBdww
#6 3151094.5_6.interdiff.txt3.41 KBdww
#6 3151094-6.patch4.58 KBdww
#5 interdiff_3-5.txt1.74 KBravi.shankar
#5 3151094-5.patch2.35 KBravi.shankar
#3 3151094-3.patch614 bytesdww
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Issue summary: View changes
dww’s picture

Issue summary: View changes
Status: Active » Needs work
FileSize
614 bytes

Gets us started with core/lib/Drupal/Core/Template/Loader/StringLoader.php
NW for core/lib/Drupal/Core/Template/TwigSandboxPolicy.php

dww’s picture

Issue summary: View changes

Moving this to a separate task:

  • Decide if we need to touch core/lib/Drupal/Core/Template/Attribute.php too. Only 'black-cat' and 'white-cat' and friends. Seems we could leave those.
ravi.shankar’s picture

Status: Needs work » Needs review
FileSize
2.35 KB
1.74 KB

Here I have tried to address comment #3.

dww’s picture

Re: #5: Thanks, but you didn't touch any of the variables with "whitelist" in their names. :( That's the point of this issue.

Here's a patch that actually completes work for the scope of this issue.

One concern:

-    $this->whitelisted_prefixes = Settings::get('twig_sandbox_whitelisted_prefixes', [
+    $this->allowed_prefixes = Settings::get('twig_sandbox_allowed_prefixes', [

I don't see that setting documented anywhere, so I don't see where to change the example for this.

More concerning, perhaps for BC we need to read and honor the old value, too? And trigger a deprecation warning or something?

At least we'll need a CR that this setting (and these protected variables) have changed.

dww’s picture

Status: Needs review » Needs work

The last submitted patch, 6: 3151094-6.patch, failed testing. View results

dww’s picture

Status: Needs work » Needs review
alexpott’s picture

Status: Needs review » Needs work
+++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
@@ -12,48 +12,48 @@
-    // Allow settings.php to override our default whitelisted classes, methods,
-    // and prefixes.
-    $whitelisted_classes = Settings::get('twig_sandbox_whitelisted_classes', [
+    // Allow settings.php to override our default allowed classes, methods, and
+    // prefixes.
+    $allowed_classes = Settings::get('twig_sandbox_allowed_classes', [

I think we need to continue to support the old setting but deprecate it. So we can safely remove it in Drupal 10.

alexpott’s picture

Also looking in contrib I'm not sure what http://codcontrib.hank.vps-private.net/node/30453440 is about

dww’s picture

Status: Needs work » Needs review
FileSize
5.32 KB
1.56 KB

Re: #10 - yup, I thought so at #6.

Like so?

dww’s picture

Status: Needs review » Needs work

Whoops, I missed. There are 3 such settings. :( New patch coming soon.

Meanwhile, other googling:

https://www.drupal.org/project/twig_domquery mentions the legacy setting in its project description. I guess we can open an issue in there to ask them to move to the new setting once this lands?

dww’s picture

FileSize
6.8 KB
2.42 KB

Let's try this. ;)

Hope it's self-documenting from the code, but the approach in all 3 cases is we check for the new setting first. Only if it's empty to do we check for the old setting. If that's defined, we @trigger_error() but use it. If that's also empty, we provide the hard-coded defaults.

dww’s picture

Updated the CR to document the settings changes.

Also, what's the policy for editing prior CRs in cases like this?

Theme system restricts which object methods can be accessed from templates

Thanks,
-Derek

dww’s picture

Status: Needs work » Needs review

Whoops, sorry

dww’s picture

Re: #11 -- yeah, not clear WTF is going on there, either. ;) Maybe we should open an issue in https://www.drupal.org/project/issues/twig_extender about it?

jungle’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
    @@ -12,63 +12,96 @@
    +    // Flip the array so we can check using isset().
    +    $this->allowed_classes = array_flip($allowed_classes);
    ...
    +    // Flip the array so we can check using isset().
    +    $this->allowed_methods = array_flip($allowed_methods);
    ...
    +    $this->allowed_prefixes = $allowed_prefixes;
    

    To keep consistency, the last one should be:

    // Flip the array so we can check using isset().
    $this->allowed_prefixes = array_flip($allowed_prefixes);
    

    (Including the comment)

  2. Hope it's self-documenting from the code, but the approach in all 3 cases is we check for the new setting first. Only if it's empty to do we check for the old setting. If that's defined, we @trigger_error() but use it. If that's also empty, we provide the hard-coded defaults.

    +1 to the logic.

  3. Also, what's the policy for editing prior CRs in cases like this?

    Not found, maybe we can ask it in the #documentation channel.

  4. Re #17, +1 to open one new issue there, no obvious harm to have one more issue :)

NW for the point 1, otherwise it's RTBC to me.

Thanks!

jungle’s picture

      if (!empty($legacy_allowed_prefixes)) {
        @trigger_error('The "twig_sandbox_whitelisted_prefixes" setting is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use "twig_sandbox_allowed_prefixes" instead. See https://www.drupal.org/node/3162897.', E_USER_DEPRECATED);
        $allowed_prefixes = $legacy_allowed_prefixes;
      }
      // Provide a default.
      $allowed_prefixes = [
        'get',
        'has',
        'is',
      ];

In addition to #18.1, missing else

dww’s picture

Status: Needs work » Needs review

Thanks for the review!

However, please look at the full code for core/lib/Drupal/Core/Template/TwigSandboxPolicy.php:

    // If the method name starts with an allowed prefix, allow it. Note:
    // strpos() is between 3x and 7x faster than preg_match() in this case.
    foreach ($this->allowed_prefixes as $prefix) {
      if (strpos($method, $prefix) === 0) {
        return TRUE;
      }
    }

We don't want to array_flip(), or we'll break this. I *almost* added a comment to that effect in #14, but thought it might be considered scope creep. ;)

dww’s picture

Assigned: Unassigned » dww
Status: Needs review » Needs work

Whoops, x-post! #19 is definitely a bug. ;)

1 moment....

dww’s picture

Assigned: dww » Unassigned
Status: Needs work » Needs review
FileSize
6.83 KB
612 bytes
jungle’s picture

Status: Needs review » Reviewed & tested by the community

#20 is right, ignore #18.1 please.

  1. +++ b/core/lib/Drupal/Core/Template/Loader/StringLoader.php
    @@ -8,7 +8,7 @@
    - * This loader is intended to be used in a Twig loader chain and whitelists
    + * This loader is intended to be used in a Twig loader chain and only loads
    
    +++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
    @@ -12,63 +12,98 @@
    - * objects can do by whitelisting certain classes, method names, and method
    + * objects can do by only loading certain classes, method names, and method
    

    whitelists -> only loads, whitelisting -> only loading, good.

  2. +++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
    @@ -12,63 +12,98 @@
    -   * An array of whitelisted methods in the form of methodName => TRUE.
    +   * An array of allowed methods in the form of methodName => TRUE.
    ...
    -  protected $whitelisted_methods;
    +  protected $allowed_methods;
    

    whitelisted methods -> allowed methods, good

  3. +++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
    @@ -12,63 +12,98 @@
    -  protected $whitelisted_prefixes;
    +  protected $allowed_prefixes;
    ...
    +    $this->allowed_prefixes = $allowed_prefixes;
    
    @@ -85,20 +120,20 @@ public function checkPropertyAllowed($obj, $property) {}
    +    foreach ($this->allowed_prefixes as $prefix) {
    

    whitelisted prefixes -> allowed prefixes, good

  4. +++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
    @@ -12,63 +12,98 @@
    -  protected $whitelisted_classes;
    +  protected $allowed_classes;
    

    whitelisted classes -> allowed classes, good

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

So looking at the deprecation code it reminds me that I think we should generalise the approach to renaming settings we used for config_sync_directory in Drupal 8. I.e. we should have a map of deprecated settings to new settings with the deprecation information too. We should open a blocking issue to do that because atm we have no test coverage of the BC layer added here. Whereas if we relied on a generic (and tested) Settings deprecation process it'd more reliable and we'd have less hunks of complex code here.

dww’s picture

Agreed, that'd be better.
#3151093: Replace use of whitelist/blacklist in \Drupal\Core\Security\RequestSanitizer and its test has \Drupal\Core\Site\Settings::handleDeprecations().
Is that how you want that to work?
Do you want to split that part out to a separate issue?
Or just land that as-is and we'll build on it here?

Thanks!
-Derek

alexpott’s picture

Title: Replace use of whitelist/blacklist in \Drupal\Core\Template classes and their tests » [pp-1] Replace use of whitelist/blacklist in \Drupal\Core\Template classes and their tests
Status: Needs work » Postponed
dww’s picture

Proof of concept for #3163226-13: Add the ability to deprecate a Settings name

Here's #22 cleaned up / simplified, plus #3163226-13.

jungle’s picture

+++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php
@@ -62,9 +62,10 @@ public function __construct() {
+    $allowed_prefixes = Settings::get('twig_sandbox_allowed_prefixes', [

BTW, missing $this->allowed_prefixes = $allowed_prefixes;

dww’s picture

Good catch, thanks! 2 new patches:

  1. 3151094-29.with-3163226-21.patch will hopefully run / pass tests now. ;) It's fixed version of #27 plus the latest from #3163226-21: Add the ability to deprecate a Settings name
  2. 3151094-29.after-3163226.do-not-test.patch is just the changes for this issue once #3163226 is committed. "do-not-test" since it won't apply until that lands.
dww’s picture

New patches based on changes at #3163226: Add the ability to deprecate a Settings name

  1. Instead of extending the existing test, add new test plumbing for testing real deprecations.
  2. Settings::$deprecatedSettings is now keyed by legacy name.

Here's a do-not-test that will only apply after #3163226-37 is committed and a version with #3163226-37 included and drupalci.yml change to only run the new test.

Also cleaning up the summary + remaining tasks now that this is nearly complete.

Thanks,
-Derek

dww’s picture

Issue summary: View changes

Open questions:

  1. Given that #3163226: Add the ability to deprecate a Settings name is already testing all 6 combinations of settings.php and Settings::get(), and ensuring that we always get the correct value returned and that the deprecation message is generated in the 5 expected cases, do we even need to be testing the real deprecations at all?
  2. If so, do we have to test all 6 combos for every new deprecated setting? :( Or can we have a simple test for real deprecations? What do we actually care about testing for these real deprecations?

Testing the real deprecations seems a bit like busy-work to me. If we trust the new API, can't we just use it without re-testing it for every usage? It's more churn when we deprecate, and more stuff to cleanup at the next major.

Thoughts?

Thanks!
-Derek

dww’s picture

jungle’s picture

Re #31, Good question! How about the following, just to test that it works, no data provider -- triggered expected deprecation message(s).

  /**
   * Tests legacy twig_sandbox_* settings.
   *
   * @group legacy
   *
   * @expectedDeprecation The "twig_sandbox_whitelisted_classes" setting is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use "twig_sandbox_allowed_classes" instead. See https://www.drupal.org/node/3162897.
   * @expectedDeprecation The "twig_sandbox_whitelisted_methods" setting is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use "twig_sandbox_allowed_methods" instead. See https://www.drupal.org/node/3162897.
   * @expectedDeprecation The "twig_sandbox_whitelisted_prefixes" setting is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use "twig_sandbox_allowed_prefixes" instead. See https://www.drupal.org/node/3162897.
   */
  public function testLegacyTwigSandboxSettings(): void {
    $settings = <<<'EOD'
<?php
$settings['twig_sandbox_whitelisted_classes'] = ['a', 'b'];
$settings['twig_sandbox_whitelisted_methods'] = ['aFoo', 'bBar'];
$settings['twig_sandbox_whitelisted_prefixes'] = ['aPrefix', 'bPrefix'];
EOD;
    $class_loader = NULL;
    $vfs_root = vfsStream::setup('root');
    $sites_directory = vfsStream::newDirectory('sites')->at($vfs_root);
    vfsStream::newFile('settings.php')
      ->at($sites_directory)
      ->setContent($settings);
    Settings::initialize(vfsStream::url('root'), 'sites', $class_loader);
    $this->assertEquals(['a', 'b'], Settings::get('twig_sandbox_whitelisted_classes'));
    $this->assertEquals(['a', 'b'], Settings::get('twig_sandbox_allowed_classes'));
    $this->assertEquals(['aFoo', 'bBar'], Settings::get('twig_sandbox_whitelisted_methods'));
    $this->assertEquals(['aFoo', 'bBar'], Settings::get('twig_sandbox_allowed_methods'));
    $this->assertEquals(['aPrefix', 'bPrefix'], Settings::get('twig_sandbox_whitelisted_prefixes'));
    $this->assertEquals(['aPrefix', 'bPrefix'], Settings::get('twig_sandbox_allowed_prefixes'));
  }

jungle’s picture

Even more, remove assertions, only care deprecation message(s)

    $this->assertEquals(['a', 'b'], Settings::get('twig_sandbox_whitelisted_classes'));
    $this->assertEquals(['a', 'b'], Settings::get('twig_sandbox_allowed_classes'));
    $this->assertEquals(['aFoo', 'bBar'], Settings::get('twig_sandbox_whitelisted_methods'));
    $this->assertEquals(['aFoo', 'bBar'], Settings::get('twig_sandbox_allowed_methods'));
    $this->assertEquals(['aPrefix', 'bPrefix'], Settings::get('twig_sandbox_whitelisted_prefixes'));
    $this->assertEquals(['aPrefix', 'bPrefix'], Settings::get('twig_sandbox_allowed_prefixes'));
dww’s picture

Title: [pp-1] Replace use of whitelist/blacklist in \Drupal\Core\Template classes and their tests » Replace use of whitelist/blacklist in \Drupal\Core\Template classes and their tests
Status: Postponed » Needs review

Yay, blocker is in! This can proceed. Queued #32 for a test run.

jungle’s picture

@dww, could you add the test suggested in #33 and #34 if you agree?

Missing test for the newly added deprecated settings, I am afraid I could not RTBC this.

dww’s picture

Issue summary: View changes
Issue tags: +Needs framework manager review

I'm waiting for a core committer to answer #31.1. As I wrote there, I believe if we trust the tests for the Settings::$deprecatedSettings array / API (as we should), then adding "real" deprecation tests for every deprecated setting seems like pointless churn to me. Once we have tests for a given form element, we don't re-test that form element every time we use it. I don't see why we need anything more than #32.

Tagging for framework manager review.

Of course if they want more, we can add them. Not sure if #34/ #35 is enough, or we should have a dataProvider, or what. If they want real deprecation tests, we need clarity on their preferred approach, and an answer to #31.2: do we need to test all 6 possible cases for each setting? If not, which subset is enough? Etc.

Thanks,
-Derek

alexpott’s picture

Once we have tests for a given form element, we don't re-test that form element every time we use it.

Yes we don't test for every detail but we do often test for the presence and effect of the form field. I think we need a single test showing the deprecation is triggered as expected.

dww’s picture

Re: #38: Groovy, thanks for clarifying!

Re: #33:

+  Since symfony/phpunit-bridge 5.1: Using "@expectedDeprecation" annotations in tests is deprecated, use the "ExpectDeprecationTrait::expectDeprecation()" method instead.

;)

With an eye towards #3151093: Replace use of whitelist/blacklist in \Drupal\Core\Security\RequestSanitizer and its test I'm going with a @dataProvider approach.

Do we want each setting in its own case, or can we group them to test all deprecated twig_sandbox_* settings in 1 case like I'm doing here?

Thanks,
-Derek

The last submitted patch, 39: 3151094-39.test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dww’s picture

FileSize
9.49 KB
1 KB

Whoops, comment spacing isn't quite right. ;)

This should be better.

dww’s picture

Before:

% phpcs --standard=Drupal --extensions=php,module,inc,install,test,profile,theme,css,md,yml SettingsTest.php
------------------------------------------------------------------------------------
FOUND 6 ERRORS AFFECTING 6 LINES
------------------------------------------------------------------------------------
  73 | ERROR | [x] Doc comment short description must end with a full stop
  98 | ERROR | [ ] Description for the @return value is missing
 160 | ERROR | [x] There must be exactly one blank line before the tags in a doc
     |       |     comment
 163 | ERROR | [ ] Parameter tags must be defined first in a doc comment
 219 | ERROR | [x] There must be exactly one blank line before the tags in a doc
     |       |     comment
 292 | ERROR | [x] Additional blank lines found at end of doc comment

After:

% phpcs --standard=Drupal --extensions=php,module,inc,install,test,profile,theme,css,md,yml SettingsTest.php
------------------------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 3 LINES
------------------------------------------------------------------------------------
  73 | ERROR | [x] Doc comment short description must end with a full stop
  98 | ERROR | [ ] Description for the @return value is missing
 164 | ERROR | [ ] Parameter tags must be defined first in a doc comment

(these 3 are pre-existing).

dww’s picture

If we move each setting into a separate case from the dataProvider, we can simplify some of these even further and shrink the patch.

Also fixing a typo in a @param comment s/stinrg/string/

dww’s picture

And if we want to get really clever, we can auto-populate providerTestRealDeprecatedSettings() via Settings::$deprecatedSettings itself. ;) Then we never have to touch this file and we know that all deprecated settings will be tested.

Probably this will be considered too much magic and we'll have to stick with #43, but I'm uploading for comparison / consideration, just in case. ;)

jungle’s picture

If i change $this->addExpectedDeprecationMessage($expected_deprecation); to $this->expectDeprecationMessage($expected_deprecation);, it won't pass. wondering what's the difference between them. If you know, would you mind to share? Thanks!

dww’s picture

I confess to not fully understanding. I can say that addExpectedDeprecationMessage() is from Drupal\Tests\Traits\ExpectDeprecationTrait. Although, yikes, apparently that's on its way out, too: #3157434: Deprecate \Drupal\Tests\Traits\ExpectDeprecationTrait in favour of \Symfony\Bridge\PhpUnit\ExpectDeprecationTrait ;)

However, expectDeprecationMessage() is native to PHPUnit itself.

My (limited) understanding is that the Symfony PHPUnit bridge catches all deprecation warnings thrown and has its own handling of them so we can ignore a huge # of deprecations that we can't do anything about until we stop supporting older versions of PHP, PHPUnit, Symfony, etc, etc. Therefore, we need to use that plumbing to inspect deprecations, since if we ask PHPUnit itself to expect something, it'll never be seen. Or something. ;)

I'm sure @alexpott can completely school us on the details. ;)

jungle’s picture

Thanks @dww, I do not fully get #46, but after fixing/rerolling the patch for the issue you shared, I think we can try the following changes:

--- a/core/tests/Drupal/Tests/Core/Site/SettingsTest.php
+++ b/core/tests/Drupal/Tests/Core/Site/SettingsTest.php
@@ -3,9 +3,9 @@
 namespace Drupal\Tests\Core\Site;
 
 use Drupal\Core\Site\Settings;
-use Drupal\Tests\Traits\ExpectDeprecationTrait;
 use Drupal\Tests\UnitTestCase;
 use org\bovigo\vfs\vfsStream;
+use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
 
 /**
  * @coversDefaultClass \Drupal\Core\Site\Settings
@@ -206,7 +206,7 @@ public function testFakeDeprecatedSettings(array $settings_config, string $setti
     $instance_property->setValue($deprecated_settings);
 
     if ($expect_deprecation_message) {
-      $this->addExpectedDeprecationMessage($deprecated_setting['message']);
+      $this->expectDeprecation($deprecated_setting['message']);
     }
 
     Settings::initialize(vfsStream::url('root'), 'sites', $class_loader);
@@ -301,7 +301,7 @@ public function testRealDeprecatedSettings(string $legacy_setting, string $expec
       ->at($sites_directory)
       ->setContent($settings_file_content);
 
-    $this->addExpectedDeprecationMessage($expected_deprecation);
+    $this->expectDeprecation($expected_deprecation);

expectDeprecation() (or similar) is more accurate/suitable than addExpectedDeprecationMessage(), IMO.

dww’s picture

Thanks for reviewing. However, #47 is out of scope here. This test was already using Drupal\Tests\Traits\ExpectDeprecationTrait before I started touching it at #3163226: Add the ability to deprecate a Settings name. I don't see any existing references to Symfony\Bridge\PhpUnit\ExpectDeprecationTrait anywhere in the 9.1.x branch (yet). Converting from our custom version of this trait to the Symfony\Bridge version should happen at #3157434: Deprecate \Drupal\Tests\Traits\ExpectDeprecationTrait in favour of \Symfony\Bridge\PhpUnit\ExpectDeprecationTrait, not here. If that lands first, it should make those changes itself to this test as it exists in the 9.1.x branch. If/when that happens, then we can re-roll this to use expectDeprecation() on the new instances. But until then, we should definitely leave this as-is.

Cheers,
-Derek

jungle’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
8.56 KB
3.16 KB

Thanks @dww.

Then #44 is RTBC to me, one test covers all real deprecated settings magically. Deprecated settings added later on do not need to add tests anymore. However, #33 + #34 is an alternative to me still, so uploading a patch based on it, for committer's reference.

jungle’s picture

FileSize
7.81 KB
1.01 KB
+++ b/core/tests/Drupal/Tests/Core/Site/SettingsTest.php
@@ -158,6 +158,9 @@ public function testGetInstanceReflection() {
+   * @see self::testRealDeprecatedSettings()
+   * @see self::providerTestRealDeprecatedSettings()

@@ -213,6 +216,10 @@ public function testFakeDeprecatedSettings(array $settings_config, string $setti
+   * Note: Tests for real deprecated settings should not be added here.
+   *
+   * @see self::providerTestRealDeprecatedSettings()
+   *

Sorry the above should be removed from #49

dww’s picture

Issue summary: View changes
FileSize
8.93 KB

IMHO #44 is the best option, and will be zero work for subsequent issues. Re-uploading that, since I think we both agree that's RTBC, whereas #34 / #35 / #50 is an alternative / 2nd choice if committers prefer. Honestly, I'd consider #50 the third choice. If #44 is too much magic, I'd rather go with #43 than #50.

So I'm re-uploading #44 to be the last patch in the issue for both testbot and committer review.
I also put all of this into the summary as the final remaining task.

Thanks,
-Derek

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I looked at #51 and was thinking I wish it was more declarative. But then looking at #43 that seems a bit off. I think the correct patch is #50. It's testing that if you have the setting in your setting.php you get the expected deprecation.

+++ b/core/tests/Drupal/Tests/Core/Site/SettingsTest.php
@@ -272,4 +272,29 @@ public function providerTestFakeDeprecatedSettings(): array {
+  /**
+   * Tests legacy twig_sandbox_* settings.
+   *
+   * @group legacy
+   *
+   * @expectedDeprecation The "twig_sandbox_whitelisted_classes" setting is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use "twig_sandbox_allowed_classes" instead. See https://www.drupal.org/node/3162897.
+   * @expectedDeprecation The "twig_sandbox_whitelisted_methods" setting is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use "twig_sandbox_allowed_methods" instead. See https://www.drupal.org/node/3162897.
+   * @expectedDeprecation The "twig_sandbox_whitelisted_prefixes" setting is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use "twig_sandbox_allowed_prefixes" instead. See https://www.drupal.org/node/3162897.
+   */
+  public function testLegacyTwigSandboxSettings(): void {

Should have the @runInSeparateProcess annotation. In fact we should file a follow-up to move this annotation to the class because there are so many statics involved with the Settings.

jungle’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: +Needs followup
FileSize
7.84 KB
690 bytes

Thanks @alexpott. Added @runInSeparateProcess

jungle’s picture

Follow up filed

Not sure we should add it to the class or add it to all methods in SettingsTest, as per the official docs, it does not tell that the annotation is applicable to class explicitly.

Comments are welcome over there.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed a2856d1 and pushed to 9.1.x. Thanks!

  • alexpott committed a2856d1 on 9.1.x
    Issue #3151094 by dww, jungle, ravi.shankar, alexpott: Replace use of...
dww’s picture

Re: #52: Thanks for making a decision. You wanted more declarative than #51 / #44 -- spell it out, use less magic. ;) Fair enough. More work for each deprecated setting, but we've only got 4 of them at this point. Unlike other kinds of deprecations, there are unlikely to be a huge # of these.

I'm slightly bummed we'll have to repeat all of this in each test:

+++ b/core/tests/Drupal/Tests/Core/Site/SettingsTest.php
@@ -272,4 +272,31 @@ public function providerTestFakeDeprecatedSettings(): array {
+    $class_loader = NULL;
+    $vfs_root = vfsStream::setup('root');
+    $sites_directory = vfsStream::newDirectory('sites')->at($vfs_root);
+    vfsStream::newFile('settings.php')
+      ->at($sites_directory)
+      ->setContent($settings);
+    Settings::initialize(vfsStream::url('root'), 'sites', $class_loader);

Which is why I was advocating for #43 with a @dataProvider as the alternative. That still has the same desired effect:

It's testing that if you have the setting in your setting.php you get the expected deprecation.

That's what all 3 approaches do. ;)

Anyway, if you're happy with copy/pasta on this, we can move on. Just trying to better understand your thinking / preferences to calibrate my own for future work.

Re: #54: Thanks for opening that! Now that I know PHPUnit has this plumbing, I was thinking the same for this whole test class. Commented there with a patch. ;)

Status: Fixed » Closed (fixed)

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