Skip to content

[BUG] Pluggable functions like get_avatar() don't work in integration tests when using Valet #785

@jerclarke

Description

@jerclarke

Environment
OS: MacOS
PHP version: 8.3.22
Installed Codeception version: 5.3.2
Installed wp-browser version: 4.5.5
WordPress version: 6.8.2
Local development environment: Valet (Works if tested in MAMP)
WordPress structure and management: Default

Can you perform the test manually?
Yes. When running the same test plugin code in browser, get_avatar() shows the filtered HTML rather than default.

Codeception configuration file
Paste, in a fenced YAML block, the content of your Codeception configuration file; remove any sensitive data!

namespace: Tests
support_namespace: Support
paths:
    tests: tests
    output: tests/_output
    data: tests/Support/Data
    support: tests/Support
    envs: tests/_envs
actor_suffix: Tester
params:
    - tests/.env
extensions:
    enabled:
        - Codeception\Extension\RunFailed
        - lucatume\WPBrowser\Extension\ChromeDriverController
        - lucatume\WPBrowser\Extension\BuiltInServerController
        - lucatume\WPBrowser\Extension\Symlinker
    config:
        lucatume\WPBrowser\Extension\ChromeDriverController:
            port: '%CHROMEDRIVER_PORT%'
        lucatume\WPBrowser\Extension\BuiltInServerController:
            workers: 5
            port: '%BUILTIN_SERVER_PORT%'
            docroot: '%WORDPRESS_ROOT_DIR%'
            env:
                DATABASE_TYPE: sqlite
                DB_ENGINE: sqlite
                DB_DIR: '%codecept_root_dir%/tests/Support/Data'
                DB_FILE: db.sqlite
        lucatume\WPBrowser\Extension\Symlinker:
            wpRootFolder: '%WORDPRESS_ROOT_DIR%'
            plugins:
                - .
    commands:
        - lucatume\WPBrowser\Command\RunOriginal
        - lucatume\WPBrowser\Command\RunAll
        - lucatume\WPBrowser\Command\GenerateWPUnit
        - lucatume\WPBrowser\Command\DbExport
        - lucatume\WPBrowser\Command\DbImport
        - lucatume\WPBrowser\Command\MonkeyCachePath
        - lucatume\WPBrowser\Command\MonkeyCacheClear
        - lucatume\WPBrowser\Command\DevStart
        - lucatume\WPBrowser\Command\DevStop
        - lucatume\WPBrowser\Command\DevInfo
        - lucatume\WPBrowser\Command\DevRestart
        - lucatume\WPBrowser\Command\ChromedriverUpdate

Suite configuration file
Paste, in a fenced YAML block, the content of the suite configuration file; remove any sensitive data!

actor: IntegrationTester
bootstrap: _bootstrap.php
modules:
    enabled:
        - lucatume\WPBrowser\Module\WPLoader

    config:
        lucatume\WPBrowser\Module\WPLoader:
           wpRootFolder: "%WORDPRESS_ROOT_DIR%" 
           dbUrl: '%WORDPRESS_DB_URL%'
           wpDebug: true
           tablePrefix: '%TEST_TABLE_PREFIX%'
           domain: '%WORDPRESS_DOMAIN%'
           adminEmail: 'admin@%WORDPRESS_DOMAIN%'
           title: 'Integration Tests'
           plugins: ['./newwpbrowsertestplugin.php']
           theme: ''
           skipPluggables: true

Describe the bug

Our site uses a plugged version of get_avatar() and I've historically had wpunit tests to confirm it's "plugged". This worked in my old setup with MAMP, never had any issue, it just did what made sense and a simple test confirmed the output was our version and not the one from core WP.

But I recently switched to using Valet and now it no longer works. Our old tests that worked on MAMP fail in Valet, and as far as I can tell, the "plugging" just doesn't work.

My old setup is really complex and different from the current default WP-Browser setup, so I confirmed this also fails in a test site that uses pretty much the out-of-box config, as you can see above. In the process I also created fresh, ultra-simple tests (below) to confirm that plugging fails for both get_avatar() and get_userdata().

I also tested two configurations: One using the default /tests/_wordpress/ setup, and another the way I normally set things up, where the tests instead load WP from the root directory of the site. It seemed to happen in both scenarios.

It sounds like you already have WP-Browser working with Valet, so I wonder if you'll be able to reproduce the issue, or if it's something on my end. Maybe you just never tested a plugged function in that context?

To Reproduce

  • Create a brand new plugin and add default WP-Browser setup
  • Override a pluggable.php function in the plugin
  • Works in browser
  • Fails in Integration tests

Here's my demo plugin code:

if (!function_exists( 'get_avatar' )) {

	function get_avatar( $id_or_email, $size = 96, $default_value = '', $alt = '', $args = null) {

		return "<img class='avatar' height=$size width=$size src='https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'>";
	}
}

if (!function_exists( 'get_userdata' )) {

	function get_userdata( $user_id ) {
		$user = get_user_by( 'id', $user_id );
		if ( is_object( $user ) ) {
			$user->user_nicename .= " PLUGGED";
		}
		return $user;
	}
}

Here's the tests I added to TestCustomTestCaseTest.php:

   public function test_pluggable_get_userdata_by_is_plugged() {

        $user = get_user_by( 'id', 1 );

        $plugged_userdata = get_userdata( 1 );

        $this->assertSame( $user->user_nicename . " PLUGGED", $plugged_userdata->user_nicename );
    }

    public function test_pluggable_get_avatar_is_plugged() {

        $avatar = get_avatar( 1 );

        $this->assertSame( "<img class='avatar' height=96 width=96 src='https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'>", $avatar );
    }

Expected behavior
Integration tests should "see" the plugged version of the function from the plugin file, rather than the default ones.

Additional context

I dug around with Xdebug trying to figure out why it doesn't load the correct version, but it made my head spin because codeception seems to do multiple loads of the plugin, and sometimes it does get overridden, while others it doesn't. For example, if I make a plugged version of get_userdata() that throws errors, the whole test suite will crash because it's loading users as part of setup. So clearly the plugged version is "there" and gets loaded, but for whatever reason it's not the version I get in the Integration tests.

Thanks as always for your help and work on WP-Browser!

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions