Sentinel schema guard test enumerates fewer plugins on 3.1.x, so regressions can go undetected

Problem/Motivation

tests/src/Kernel/EcaTokenSelectOptionSchemaTest.php, added in #3590375 (closed), walks every event, condition and action plugin at runtime, collects the form elements carrying '#eca_token_select_option' => TRUE, and asserts that each corresponding config schema key accepts the _eca_token sentinel (and '' where the element is not required).

Its value depends entirely on enumerating every plugin. On 3.1.x it does not, for two compounding reasons:

  1. A plugin that fails to instantiate is skipped. Actions::createInstance() (src/Service/Actions.php:134-150) catches \Throwable, logs, and returns NULL; Actions::actions() then skips it (:113). SetEcaLogLevel throws a TypeError in create() when eca.settings is absent — see the dedicated issue for that defect — so the plugin is dropped from the enumeration.
  2. The plugin list is statically cached before the test can install config. Actions::actions() caches through drupal_static('eca_actions'), and module installation populates that static before setUp() has a chance to install the required configuration. Installing the config afterwards therefore has no effect on an already-cached list.

The 3.0.x backport of #3590375 (closed) hit this: the very first run of the ported test enumerated fewer plugins than expected. Adding installConfig(['eca', 'user']) and drupal_static_reset('eca_actions') to setUp() raised enumeration from 353 to 356 plugins and from 98 to 99 sentinel elements, and the newly visible key was then actually asserted.

3.1.x has the same blind spot, because the fix was made during the backport and never ported forward. The schema on 3.1.x is correct — action.configuration.eca_set_eca_log_level.log_level is EcaChoice at modules/base/config/schema/eca_base.schema.yml:503-504, because the original audit enumerated the sentinel statically rather than at runtime. So there is no validation defect today. The problem is that the guard would not notice if that key regressed, which defeats the purpose of having the guard.

The result is the counter-intuitive situation that the guard on the stable 3.0.x branch is stronger than the guard on 3.1.x.

Steps to reproduce

  1. On 3.1.x, run EcaTokenSelectOptionSchemaTest and note the number of plugins and sentinel elements it enumerates.
  2. Revert action.configuration.eca_set_eca_log_level.log_level from EcaChoice back to Choice.
  3. Run the test again.

Result: the test still passes — the regression is not detected. Expected: the test fails, because that key offers "Defined by token" and no longer accepts the sentinel.

Proposed resolution

Port the 3.0.x test fix forward to 3.1.x: install the configuration the plugins need in setUp() and reset the eca_actions static so the plugin list is built after that configuration exists.

Worth considering as a follow-up: have the test assert the enumerated plugin count is non-decreasing, or fail explicitly when Actions::createInstance() returned NULL for any definition. A guard whose coverage can silently shrink has the same weakness this issue describes, one level up.

Remaining tasks

  • Port installConfig + drupal_static_reset('eca_actions') to the 3.1.x test
  • Verify the enumeration count increases and the newly visible key is asserted
  • Confirm the guard now fails when that key is reverted to plain Choice
  • Consider guarding against future silent shrinkage of the enumeration

User interface changes

None.

Data model changes

None.


Related: #3590375 (closed) introduced the test; the enumeration fix was made while backporting it to 3.0.x. The underlying instantiation failure is filed separately.

This is a test-only change, fully covered by automated tests, so per the module's contribution guidance no manual review recipe is needed.

AI-Generated: Yes (Used OpenCode to backport #3590375 (closed) to 3.0.x, where this gap was discovered and fixed; all file and line references were verified against the 3.1.x source.)