craftcms / craftcms/cms

Attaching a behavior to `currentSite` differs between unit tests and web request

Open
#10,043 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
PHP
Stars
3.6k
Forks
705
Avg merge
1d 5h
Merged PRs (30d)
134

Description

Description

I'm attaching some custom behaviors to the Site model. It seems like currentSite is created and set before I can add the the Site::EVENT_DEFINE_BEHAVIORS event listener. As a workaround, I'm setting the behavior directly on the currentSite in my module's init method.

public function init()
{
  parent::init();

  Craft::$app->sites->currentSite->attachBehavior('site-behavior', SiteBehavior::class);
}

This works fine on web requests, but when running unit tests, things seem to bootstrap in a different order.

Calling Craft::$app->sites->currentSite throws a SiteNotFoundException.

See: https://github.com/craftcms/cms/blob/develop/src/services/Sites.php#L515-L522

If I wrap the above code in a try/catch then my tests all run correctly. I can't test for the presence of currentSite or primarySite because they both throw an exception.

public function init()
{
  parent::init();

  try {
    Craft::$app->sites->currentSite->attachBehavior('site-behavior', SiteBehavior::class);
  } catch (Exception $e) {
    Event::on(
        Site::class,
        Site::EVENT_DEFINE_BEHAVIORS,
        function (DefineBehaviorsEvent $event) {
          $event->sender->attachBehavior('site-behavior', SiteBehavior::class);
        }
      );
  }
}

Steps to reproduce
  1. Add a call to Craft::$app->sites->currentSite in the init method of a Craft Module.
  2. Run unit tests to throw a SiteNotFoundException exception.
Additional info
  • Craft version: 3.6.18
  • PHP version: 7.4.24
  • Database driver & version: MySQL 5.7.29
  • Plugins & versions:
{
    "require": {
        "akeneo/api-php-client": "^6.0",
        "am-impact/amcommand": "3.1.4",
        "clubstudioltd/craft-asset-rev": "6.0.2",
        "craftcms/aws-s3": "1.2.11",
        "craftcms/cms": "3.6.18",
        "craftcms/commerce": "3.3.0.1",
        "craftcms/commerce-stripe": "2.3.2.1",
        "craftcms/feed-me": "4.3.5.1",
        "craftcms/redactor": "2.8.5",
        "enovatedesign/craft-style-inliner": "2.3",
        "fruitstudios/linkit": "1.1.12.1",
        "http-interop/http-factory-guzzle": "^1.0",
        "hubspot/api-client": "^2.8",
        "matt-west/craft-recaptcha": "1.5.2",
        "nystudio107/craft-retour": "3.1.53",
        "nystudio107/craft-seomatic": "3.4.9",
        "php-http/guzzle6-adapter": "^2.0",
        "spatie/craft-ray": "1.1.4",
        "studioespresso/craft-scout": "dev-master",
        "superbig/craft3-imgix": "2.1.0",
        "supercool/tablemaker": "2.0.1",
        "surprisehighway/craft-avatax": "2.1.6",
        "verbb/navigation": "1.4.14",
        "verbb/postie": "2.4.10",
        "verbb/super-table": "2.6.7",
        "viget/craft-classnames": "1.0.3",
        "viget/craft-viget-base": "3.1.2",
        "vlucas/phpdotenv": "^3.4.0",
        "yiisoft/yii2-redis": "^2.0"
    },
    "require-dev": {
        "codeception/codeception": "^4.1",
        "codeception/module-asserts": "^1.0.0",
        "codeception/module-phpbrowser": "^1.0.0",
        "codeception/module-yii2": "^1.1",
        "yiisoft/yii2-shell": "^2.0.3"
    },
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/vigetlabs/craft-scout.git"
        }
    ],
    "autoload": {
        "psr-4": {
            ... ⚠️ client code hidden
        }
    },
    "config": {
        "sort-packages": true,
        "optimize-autoloader": true
    },
    "scripts": {
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ]
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/services/Sites.php around lines 515-522 and the module init code described in the issue. Compare how currentSite is initialized during web requests and unit-test bootstrap, then trace when Site::EVENT_DEFINE_BEHAVIORS is dispatched. Done means custom Site behaviors can be attached consistently without catching SiteNotFoundException.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.