Problem/Motivation

While working on adding a test for #3369063: Database exception: Unknown column 'base.' when using entity types without bundle, I noticed several unrelated test failures that also affect latest 2.1.x branch.

Test failures across: composer, cspell, phpcs, phpstan, phpunit

Steps to reproduce

Remote:
See failures in pipeline: https://git.drupalcode.org/issue/linkchecker-3369063/-/pipelines/783391

1. Cspell errors

Executing /builds/issue/linkchecker-3369063/web/core/node_modules/.bin/cspell -c .cspell.json --show-suggestions --show-context --no-progress  .
$ $CI_PROJECT_DIR/$_WEB_ROOT/core/node_modules/.bin/cspell -c .cspell.json --show-suggestions --show-context $CSPELL_PROGRESS $_CSPELL_EXTRA . || EXIT_CODE=$?
config/install/linkchecker.settings.yml:12:10     - Forbidden word (blacklist)  -- filter_blacklist:
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
config/schema/linkchecker.schema.yml:47:16     - Forbidden word (blacklist)  -- filter_blacklist:
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
migrations/d6_linkchecker_settings.yml:24:26     - Forbidden word (blacklist)  -- linkchecker_filter_blacklist
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
migrations/d6_linkchecker_settings.yml:40:19     - Forbidden word (blacklist)  -- 'extract/filter_blacklist': linkchecker_filter
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
migrations/d6_linkchecker_settings.yml:40:50     - Forbidden word (blacklist)  -- linkchecker_filter_blacklist
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
migrations/d7_linkchecker_settings.yml:24:26     - Forbidden word (blacklist)  -- linkchecker_filter_blacklist
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
migrations/d7_linkchecker_settings.yml:40:19     - Forbidden word (blacklist)  -- 'extract/filter_blacklist': linkchecker_filter
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
migrations/d7_linkchecker_settings.yml:40:50     - Forbidden word (blacklist)  -- linkchecker_filter_blacklist
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
src/Form/LinkCheckerAdminSettingsForm.php:275:38    - Forbidden word (blacklist)  -- 'linkchecker_filter_blacklist'] = [
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
src/Form/LinkCheckerAdminSettingsForm.php:278:56    - Forbidden word (blacklist)  -- get('extract.filter_blacklist'),
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
src/Form/LinkCheckerAdminSettingsForm.php:282:38    - Forbidden word (blacklist)  -- 'linkchecker_filter_blacklist'] = array_merge($form
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
src/Form/LinkCheckerAdminSettingsForm.php:282:97    - Forbidden word (blacklist)  -- 'linkchecker_filter_blacklist'], $filter_descriptions
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
src/Form/LinkCheckerAdminSettingsForm.php:512:29    - Forbidden word (blacklist)  -- set('extract.filter_blacklist', $form_state->getValue
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
src/LinkCheckerLinkInterface.php:238:22    - Forbidden word (blacklisted) -- * If link becomes blacklisted this method should return
	 Suggestions: [blocklisted*, denylisted*, backlist, backlists, blocklist]
src/LinkExtractorService.php:294:27    - Forbidden word (Blacklisted) -- return !$this->isUrlBlacklisted($url);
	 Suggestions: [Blocklisted*, Denylisted*, Backlist, Backlists, Blocklist]
src/LinkExtractorService.php:301:22    - Forbidden word (blacklisted) -- * If link becomes blacklisted this method will return
	 Suggestions: [blocklisted*, denylisted*, backlist, backlists, blocklist]
src/LinkExtractorService.php:425:23    - Forbidden word (blacklists)  -- * Verifies against blacklists, if the link status
	 Suggestions: [blocklists*, denylists*, backlists, backlist, blocklist]
src/LinkExtractorService.php:433:27    - Forbidden word (Blacklisted) -- protected function isUrlBlacklisted($url) {
	 Suggestions: [Blocklisted*, Denylisted*, Backlist, Backlists, Blocklist]
src/LinkExtractorService.php:439:25    - Forbidden word (blacklist)   -- // Is url in domain blacklist?
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
src/LinkExtractorService.php:447:17    - Forbidden word (whitelist)   -- // Protocol whitelist check (without curl
	 Suggestions: [allowlist*, whitest, whitefish, whiteouts, whitebaits]
tests/src/Functional/LinkCheckerBase.php:89:11     - Forbidden word (Blacklist)  -- // -> Blacklist / Disable URL filter
	 Suggestions: [Blocklist*, Denylist*, Backlist, blockList, BlockList]
tests/src/Functional/LinkCheckerBase.php:90:64     - Forbidden word (blacklist)  -- set('extract.filter_blacklist', ['filter_url' =>
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Functional/LinkCheckerInterfaceTest.php:93:11     - Forbidden word (Blacklist)  -- // -> Blacklist / Disable URL filter
	 Suggestions: [Blocklist*, Denylist*, Backlist, blockList, BlockList]
tests/src/Functional/LinkCheckerInterfaceTest.php:94:64     - Forbidden word (blacklist)  -- set('extract.filter_blacklist', ['filter_url' =>
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Functional/LinkCheckerLinkExtractionTest.php:270:47    - Forbidden word (blacklist)  -- the linkchecker filter blacklist works well.
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:129:16    - Forbidden word (blacklist)  -- // Disable blacklist URLs.
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:138:72    - Forbidden word (Blacklisted) -- ) + count($this->getBlacklistedUrls());
	 Suggestions: [Blocklisted*, Denylisted*, Backlist, Backlists, Blocklist]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:145:51    - Forbidden word (Blacklisted) -- getExternalUrls() + $this->getBlacklistedUrls() as $url) {
	 Suggestions: [Blocklisted*, Denylisted*, Backlist, Backlists, Blocklist]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:154:16    - Forbidden word (blacklist)   -- // Disable blacklist URLs.
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:189:11    - Forbidden word (blacklisted) -- * Test blacklisted URLs.
	 Suggestions: [blocklisted*, denylisted*, backlist, backlists, blocklist]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:191:23    - Forbidden word (Blacklisted) -- public function testBlacklistedUrls() {
	 Suggestions: [Blocklisted*, Denylisted*, Backlist, Backlists, Blocklist]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:192:15    - Forbidden word (blacklist)   -- // Enable blacklist URLs.
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:201:71    - Forbidden word (Blacklisted) -- ) - count($this->getBlacklistedUrls()) - count($this
	 Suggestions: [Blocklisted*, Denylisted*, Backlist, Backlists, Blocklist]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:208:24    - Forbidden word (Blacklisted) -- foreach ($this->getBlacklistedUrls() as $url) {
	 Suggestions: [Blocklisted*, Denylisted*, Backlist, Backlists, Blocklist]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:259:36    - Forbidden word (blacklist)   -- all link with empty blacklist.
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:266:16    - Forbidden word (blacklist)   -- // Disable blacklist URLs.
	 Suggestions: [blocklist*, denylist*, backlist, blockList, BlockList]
tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:335:14    - Forbidden word (blacklisted) -- * List of blacklisted links to test.
	 Suggestions: [blocklisted*, denylisted*, backlist, backlists, blocklist]
CSpell: Files checked: 83, Issues found: 37 in 11 files.
$ WORDS_FILE=_cspell_unrecognized_words.txt
$ UPDATED_PROJECT_DICTIONARY=_cspell_updated_project_words.txt
$ touch $_CSPELL_DICTIONARY $WORDS_FILE $UPDATED_PROJECT_DICTIONARY
$ if [ "$EXIT_CODE" != "" ]; then # collapsed multi-line command
_CSPELL_EXTRA=
CSpell: Files checked: 83, Issues found: 37 in 11 files.
The number of distinct unrecognized/misspelled words is 4
------------
blacklist
blacklisted
blacklists
whitelist
------------

2. phpunit errors:

Time: 04:18.346, Memory: 10.00 MB

There were 10 errors:

1) Drupal\Tests\linkchecker\Functional\LinkCheckerInterfaceTest::testLinkCheckerCreateNodeWithBrokenLinks
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/block_content/block_content.module:33
/var/www/html/tests/src/Functional/LinkCheckerInterfaceTest.php:80

2) Drupal\Tests\linkchecker\Functional\LinkCheckerInterfaceTest::testLinkCheckerCreateBlockWithBrokenLinks
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/block_content/block_content.module:33
/var/www/html/tests/src/Functional/LinkCheckerInterfaceTest.php:80

3) Drupal\Tests\linkchecker\Kernel\LinkCheckerLinkAccessTest::testLinkAccess
Drupal\Core\Entity\EntityMalformedException: The entity does not have an ID.

/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:456
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:168
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:340
/var/www/html/web/core/modules/user/src/Entity/Role.php:191
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:567
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:522
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:239
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:370
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:635
/var/www/html/web/core/modules/user/tests/src/Traits/UserCreationTrait.php:264
/var/www/html/web/core/modules/user/tests/src/Traits/UserCreationTrait.php:157
/var/www/html/tests/src/Kernel/LinkCheckerLinkAccessTest.php:114

4) Drupal\Tests\linkchecker\Kernel\LinkcheckerCleanUpTest::testEntityCleanup
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/node/node.module:158
/var/www/html/tests/src/Kernel/LinkcheckerCleanUpTest.php:83

5) Drupal\Tests\linkchecker\Kernel\LinkcheckerHtmlLinkExtractorTest::testHtmlExtractor
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/node/node.module:158
/var/www/html/tests/src/Kernel/LinkcheckerHtmlLinkExtractorTest.php:77

6) Drupal\Tests\linkchecker\Kernel\LinkcheckerJsonApiTest::testLinkcheckerJsonApi
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/node/node.module:158
/var/www/html/tests/src/Kernel/LinkcheckerJsonApiTest.php:53

7) Drupal\Tests\linkchecker\Kernel\LinkcheckerLinkExtractorServiceTest::testIsExists
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/node/node.module:158
/var/www/html/tests/src/Kernel/LinkcheckerLinkExtractorServiceTest.php:219

8) Drupal\Tests\linkchecker\Kernel\LinkcheckerRepair301Test::testStatusHandling
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/node/node.module:158
/var/www/html/tests/src/Kernel/LinkcheckerRepair301Test.php:145

9) Drupal\Tests\linkchecker\Kernel\LinkcheckerUnpublish404Test::testStatusHandling
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/node/node.module:158
/var/www/html/tests/src/Kernel/LinkcheckerUnpublish404Test.php:112

10) Drupal\Tests\linkchecker\Kernel\QueueLinksTest::testNumberOfItems
Drupal\Core\Field\FieldException: Attempt to create a field without a field_name.

/var/www/html/web/core/modules/field/src/Entity/FieldConfig.php:126
/var/www/html/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:204
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:236
/var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php:548
/var/www/html/web/core/modules/node/node.module:158
/var/www/html/tests/src/Kernel/QueueLinksTest.php:99

Proposed resolution

  • Replace deprecated body field helper function usage in test setup.
  • Add missing user config in test setup needed by the kernel access test.
  • Use blocklist/allowlist terminology instead of forbidden words so the cspell job passes. Use cspell:ignore on the legacy configuration and migration key names to avoid BC break. Optionally, open a follow-up to refactor out this legacy code and/or fix terminology in BC-breaking change.

Remaining tasks

  • Create MR.
  • Write a fix for each failed test (composer, cspell, phpcs, phpstan, phpunit), ideally in separate atomic commits to simplify review.
  • Get this committed quickly so other MR branches can be rebased and test are working again.

User interface changes

UI strings will be updated to avoid use of cspell forbidden term: "blacklist".

API changes

Yes. As part of the cspell test cleanup, the protected method LinkExtractorService::isUrlBlacklisted($url) is renamed to LinkExtractorService::isUrlInBlocklist($url). This is a small extensibility API change for any subclass overriding that method. On the other hand, existing stored configuration keys such as extract.filter_blacklist and migration mappings remain unchanged to avoid both opening a can of worms and to avoid potential BC breakage.

Data model changes

None.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jwilson3 created an issue. See original summary.

jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
Status: Active » Needs review

Needs Review. Pipeline tests are green!

I worked through the CI failures in sequence.

Changes made so far:

  • Replaced deprecated node_add_body_field() and block_content_add_body_field() usage in various tests with current body field creation patterns used in core (via BodyFieldCreationTrait).
  • Installed missing user config in the kernel access test to fix the role and user creation steps.
  • Fixed the cspell forbidden-word failures by updating internal code, test names, and comments from blacklist/whitelist terminology to blocklist/allowlist terminology.
  • Kept legacy config and migration key names such as extract.filter_blacklist and linkchecker_filter_blacklist unchanged for backward compatibility by using cspell:ignore where needed. A follow-up issue could be opened (if desired) to refactor out this legacy code and/or fix terminology properly in a BC-breaking change.

One small API/extensibility change is part of the cspell fix:

  • Protected method LinkExtractorService::isUrlBlacklisted($url) was renamed to LinkExtractorService::isUrlInBlocklist($url).

Important! Because that method is protected, the change only affects subclasses overriding it, not normal module configuration or stored data. This is why I deemed the method rename valid for the 2.1.x branch and shouldn't require a minor/major version bump. I updated the issue summary to note the protected method rename under API changes.

joelpittet’s picture

Status: Needs review » Reviewed & tested by the community

These changes all seem reasonable and get the tests working again. Thanks @jwilson3. I agree with your take on the blacklist changes. I guess we could do a config name change, but I am more for a quick fix here.

jwilson3’s picture

Thanks for the RTBC, Joel.

Sidenote: I reached out to @eiriksm via Drupal personal contact form not long after working on this, to see if we could get this in, but no response yet. Maybe another ping from someone else would help?

eiriksm made their first commit to this issue’s fork.

eiriksm’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for working on this

Not super excited about an "API" change, but probably fine. Not really public API anyway

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • eiriksm committed 08ee9de0 on 2.1.x authored by jwilson3
    fix: #3582328 Fix broken tests blocking CI pipeline success
    
    By:...
joelpittet’s picture

Yeah, not big on name changes either but "allowlist" and "blocklist" are more descriptive! Like think about "in the black" in financial terms even... I even used to have a saying if you're consistently wrong, you're $write ;) (in context of variable names) because the code will still work. But the humans reading it need clarity... that came from typos for the words febuary and catalog, and before I had an IDE that would tell me the typos... /end old person rant

Thanks for committing this @eirksm! Unblocks tests on other issues!

Status: Fixed » Closed (fixed)

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