Skip to content

Commit

Permalink
fix: split test running for integrations (plugins) (#2904)
Browse files Browse the repository at this point in the history
While testing integrations (ACF, etc.), all the tests were run with plugins active which lead to some inconsistencies.

Tests are split to run separately and avoid those issues.

An important change was also made on meta return type. Timber uses the same return signature than WordPress, e.g. returning an empty string when the field is empty instead of evaluating it through `empty()`.
  • Loading branch information
nlemoine committed Feb 23, 2024
1 parent 7e00eeb commit 8d03809
Show file tree
Hide file tree
Showing 16 changed files with 136 additions and 263 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/php-unit-tests.yml
Expand Up @@ -139,17 +139,16 @@ jobs:
- name: Install tests
run: bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1:${{ job.services.mysql.ports['3306'] }} ${{ matrix.wp }} true


- name: Run tests
if: ${{ !matrix.webp }}
run: composer run test:no-cov
run: composer run test
env:
WP_MULTISITE: ${{ matrix.multisite }}

- name: Run tests with coverage
if: matrix.coverage == true
run: |
composer run test:codecov
composer run test:integration:codecov
- name: Upload coverage results to Coveralls
if: matrix.coverage == true
Expand Down
2 changes: 1 addition & 1 deletion bin/install-wp-tests.sh
Expand Up @@ -14,7 +14,7 @@ SKIP_DB_CREATE=${6-false}

TMPDIR=${TMPDIR-/tmp}
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
TMPDIR=$(realpath $TMPDIR)
# TMPDIR=$(realpath $TMPDIR)
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress}

Expand Down
16 changes: 12 additions & 4 deletions composer.json
Expand Up @@ -120,9 +120,17 @@
"@test",
"@cs"
],
"test": "phpunit",
"test:codecov": "phpunit --coverage-clover ./build/logs/clover.xml",
"test:make-pot": "wp i18n make-pot src tests/languages/timber.pot --domain= && wp i18n make-pot ./tests/assets/translations ./tests/languages/timber-test.pot --domain=timber-test",
"test:no-cov": "phpunit --no-coverage"
"test": [
"@test:integration:acf",
"@test:integration:coauthors-plus",
"@test:integration:wpml",
"@test:integration"
],
"test:integration": "phpunit --no-coverage --exclude-group acf,coauthors-plus,wpml",
"test:integration:acf": "phpunit --no-coverage --group acf",
"test:integration:coauthors-plus": "phpunit --no-coverage --group coauthors-plus",
"test:integration:codecov": "phpunit --coverage-clover ./build/logs/clover.xml",
"test:integration:wpml": "phpunit --no-coverage --group wpml",
"test:make-pot": "wp i18n make-pot src tests/languages/timber.pot --domain= && wp i18n make-pot ./tests/assets/translations ./tests/languages/timber-test.pot --domain=timber-test"
}
}
7 changes: 1 addition & 6 deletions src/CoreEntity.php
Expand Up @@ -177,7 +177,7 @@ protected function fetch_meta($field_name = '', $args = [], $apply_filters = tru
$object_meta = \get_metadata($object_type, $this->ID, $field_name, true);

// Mimick $single argument when fetching all meta values.
if (empty($field_name) && \is_array($object_meta) && !empty($object_meta)) {
if (empty($field_name) && \is_array($object_meta)) {
$object_meta = \array_map(function ($meta) {
/**
* We use array_key_exists() instead of isset(), because when the meta value is null, isset() would
Expand All @@ -192,11 +192,6 @@ protected function fetch_meta($field_name = '', $args = [], $apply_filters = tru
return $meta;
}, $object_meta);
}

// Empty result.
if (empty($object_meta)) {
$object_meta = empty($field_name) ? [] : null;
}
}

if ($apply_filters) {
Expand Down
71 changes: 51 additions & 20 deletions tests/bootstrap.php
Expand Up @@ -14,35 +14,66 @@
// Get access to tests_add_filter() function.
require_once $_tests_dir . '/includes/functions.php';

/**
* Callback to manually load the plugin
*/
function _manually_load_plugin()
function tt_get_arg(string $key)
{
Timber\Timber::init();
foreach ($_SERVER['argv'] as $index => $arg) {
if ($key === substr($arg, 0, strlen($key))) {
return [
'index' => $index,
$key => str_replace("{$key}=", '', $arg),
];
}
}
return false;
}

function tt_is_group(string $group_name)
{
$group = tt_get_arg('--group');
if (false === $group) {
return false;
}

$group_name_index = ++$group['index'];

require dirname(__FILE__) . '/../wp-content/plugins/advanced-custom-fields/acf.php';
if (file_exists(dirname(__FILE__) . '/../wp-content/plugins/co-authors-plus/co-authors-plus.php')) {
include dirname(__FILE__) . '/../wp-content/plugins/co-authors-plus/co-authors-plus.php';
if (!isset($_SERVER['argv'][$group_name_index])) {
return false;
}

return ($group_name === $_SERVER['argv'][$group_name_index]);
}

// Add plugin to active mu-plugins to make sure it gets loaded.
tests_add_filter('muplugins_loaded', '_manually_load_plugin');
tests_add_filter('muplugins_loaded', function () {
// Load Timber
Timber\Timber::init();

// WPML integration
define('ICL_LANGUAGE_CODE', 'en');
if (tt_is_group('acf')) {
require __DIR__ . '/../wp-content/plugins/advanced-custom-fields/acf.php';
}

/**
* Mocked function for testing menus in WPML
*/
function wpml_object_id_filter($element_id, $element_type = 'post', $return_original_if_missing = false, $language_code = null)
{
$locations = get_nav_menu_locations();
if (isset($locations['extra-menu'])) {
return $locations['extra-menu'];
if (tt_is_group('coauthors-plus')) {
require __DIR__ . '/../wp-content/plugins/co-authors-plus/co-authors-plus.php';
}

if (tt_is_group('wpml')) {
// WPML integration
define('ICL_LANGUAGE_CODE', 'en');
}
});

if (tt_is_group('wpml')) {
/**
* Mocked function for testing menus in WPML
*/
function wpml_object_id_filter($element_id, $element_type = 'post', $return_original_if_missing = false, $language_code = null)
{
$locations = get_nav_menu_locations();
if (isset($locations['extra-menu'])) {
return $locations['extra-menu'];
}
return $element_id;
}
return $element_id;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/test-timber-cache.php
Expand Up @@ -329,7 +329,7 @@ public function testTimberLoaderCacheObject()
$clear = $loader->clear_cache_timber(Timber\Loader::CACHE_OBJECT);
$this->assertTrue($clear);
$works = true;

if (isset($wp_object_cache->cache[Timber\Loader::CACHEGROUP])
&& !empty($wp_object_cache->cache[Timber\Loader::CACHEGROUP])) {
$works = false;
Expand Down
52 changes: 0 additions & 52 deletions tests/test-timber-image-resize.php
Expand Up @@ -180,56 +180,4 @@ public function testSideloadedResize()

$this->assertEquals($expected, $sideloaded);
}

public function testWPMLurlRemote()
{
// this test replicates the url issue caused by the WPML language identifier in the url
// However, WPML can't be installed with composer so this test mocks the WPML plugin

// define ICL_LANGUAGE_CODE constant because on subsequent calls (i.e. if downloaded file exists),
// replacement done in Integrations/WPML.php will fail and trigger an error here
if (!defined('ICL_LANGUAGE_CODE')) {
define('ICL_LANGUAGE_CODE', 'en');
}

// WPML uses a filter to alter the home_url
$home_url_filter = function ($url) {
return $url . '/en';
};
add_filter('home_url', $home_url_filter, -10, 4);

$img = 'https://raw.githubusercontent.com/timber/timber/master/tests/assets/arch-2night.jpg';
// test with a local and external file
$resized = Timber\ImageHelper::resize($img, 50, 50);

// make sure the base url has not been duplicated (https://github.com/timber/timber/issues/405)
$this->assertLessThanOrEqual(1, substr_count($resized, 'example.org'));
// make sure the image has been resized
$resized = Timber\URLHelper::url_to_file_system($resized);
$this->assertTrue(TestTimberImage::checkSize($resized, 50, 50), 'image should be resized');
}

public function testWPMLurlLocal()
{
// this test replicates the url issue caused by the WPML language identifier in the url
// However, WPML can't be installed with composer so this test mocks the WPML plugin

// WPML uses a filter to alter the home_url
$home_url_filter = function ($url) {
return $url . '/en';
};
add_filter('home_url', $home_url_filter, -10, 4);

// test with a local and external file
$img = 'arch.jpg';
$img = TestTimberImage::copyTestAttachment($img);

$resized = Timber\ImageHelper::resize($img, 50, 50);

// make sure the base url has not been duplicated (https://github.com/timber/timber/issues/405)
$this->assertLessThanOrEqual(1, substr_count($resized, 'example.org'));
// make sure the image has been resized
$resized = Timber\URLHelper::url_to_file_system($resized);
$this->assertTrue(TestTimberImage::checkSize($resized, 50, 50), 'image should be resized');
}
}
41 changes: 41 additions & 0 deletions tests/test-timber-integration-acf.php
Expand Up @@ -3,13 +3,22 @@
use Timber\User;

/**
* @group acf
* @group users-api
* @group comments-api
* @group integrations
* @group posts-api
*/
class TestTimberIntegrationACF extends Timber_UnitTestCase
{
public function setUp(): void
{
if (!function_exists('get_field')) {
$this->markTestSkipped('ACF plugin is not loaded');
}
parent::setUp();
}

public function testACFGetFieldPost()
{
$post_id = $this->factory->post->create();
Expand Down Expand Up @@ -462,6 +471,38 @@ public function testACFObjectTransformsDoesNotTriggerNotice()
$this->assertSame(false, $file);
}

/**
* @ticket #824
*/
public function testTermWithNativeMetaNotExisting()
{
$tid = $this->factory->term->create([
'name' => 'News',
'taxonomy' => 'category',
]);

add_term_meta($tid, 'bar', 'qux');
;
$wp_native_value = get_term_meta($tid, 'foo', true);
$acf_native_value = get_field('foo', 'category_' . $tid);

$valid_wp_native_value = get_term_meta($tid, 'bar', true);
$valid_acf_native_value = get_field('bar', 'category_' . $tid);

$term = Timber::get_term($tid);

//test baseline "bar" data
$this->assertEquals('qux', $valid_wp_native_value);
$this->assertEquals('qux', $valid_acf_native_value);
$this->assertEquals('qux', $term->bar);

//test the one that doesn't exist
$this->assertEquals('string', gettype($wp_native_value));
$this->assertEmpty($wp_native_value);
$this->assertNull($acf_native_value);
$this->assertNotTrue($term->meta('foo'));
}

private function register_field($field_name, $field_type, $field_args = [])
{
$group_key = sprintf('group_%s', uniqid());
Expand Down
8 changes: 8 additions & 0 deletions tests/test-timber-integration-wpml.php
Expand Up @@ -6,6 +6,14 @@
*/
class TestTimberIntegrationWPML extends Timber_UnitTestCase
{
public function setUp(): void
{
if (!defined('ICL_LANGUAGE_CODE')) {
$this->markTestSkipped('WPML plugin is not loaded');
}
parent::setUp();
}

public function testFileSystemToURLWithWPML()
{
$this->add_filter_temporarily('home_url', function ($url, $path) {
Expand Down
7 changes: 4 additions & 3 deletions tests/test-timber-integrations-coauthors.php
Expand Up @@ -5,6 +5,7 @@
/**
* @group posts-api
* @group integrations
* @group coauthors-plus
*/
class TestTimberIntegrationsCoAuthors extends Timber_UnitTestCase
{
Expand All @@ -20,12 +21,12 @@ public function expectedDeprecated()
parent::expectedDeprecated();
}

public function set_up()
public function setUp(): void
{
if (!class_exists('CoAuthors_Plus')) {
return $this->markTestSkipped('CoAuthors_Plus plugin not loaded');
$this->markTestSkipped('CoAuthors Plus plugin is not loaded');
}
parent::set_up();
parent::setUp();
}

/* ----------------
Expand Down
2 changes: 1 addition & 1 deletion tests/test-timber-menu.php
Expand Up @@ -636,7 +636,7 @@ public function testMenuMetaSet()
$this->assertEquals('bar', $item->foo);
$this->assertNotEquals('bar', $item->meta('foo'));
$this->assertEquals('stardust', $item->meta('ziggy'));
$this->assertNull($item->meta('asdfafds'));
$this->assertSame('', $item->meta('asdfafds'));
}

public function testMenuMeta()
Expand Down
16 changes: 8 additions & 8 deletions tests/test-timber-meta.php
Expand Up @@ -97,10 +97,10 @@ public function testMetaReturnsNullWhenResultIsEmpty()
$user = Timber::get_user($user_id);
$comment = Timber::get_comment($comment_id);

$this->assertSame(null, $post->meta('not_found'));
$this->assertSame(null, $term->meta('not_found'));
$this->assertSame(null, $user->meta('not_found'));
$this->assertSame(null, $comment->meta('not_found'));
$this->assertSame('', $post->meta('not_found'));
$this->assertSame('', $term->meta('not_found'));
$this->assertSame('', $user->meta('not_found'));
$this->assertSame('', $comment->meta('not_found'));
}

public function testPreMetaFilter()
Expand Down Expand Up @@ -375,16 +375,16 @@ public function testRawMetaInexistent()
]
);

$this->assertSame(null, $post->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $post->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $post_string);

$this->assertSame(null, $term->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $term->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $term_string);

$this->assertSame(null, $user->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $user->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $user_string);

$this->assertSame(null, $comment->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $comment->raw_meta('my_custom_property_inexistent'));
$this->assertSame('', $comment_string);
}

Expand Down

0 comments on commit 8d03809

Please sign in to comment.