Skip to content

Commit 3890883

Browse files
committed
Sync: IDC: Add tests for 3rd party domain mapping support
1 parent 00fab3d commit 3890883

3 files changed

Lines changed: 255 additions & 49 deletions

File tree

3rd-party/domain-mapping.php

Lines changed: 100 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,113 @@
11
<?php
22

3-
if ( Jetpack_Constants::is_defined( 'SUNRISE' ) ) :
3+
/**
4+
* Class Jetpack_3rd_Party_Domain_Mapping
5+
*
6+
* This class contains methods that are used to provide compatibility between Jetpack sync and domain mapping plugins.
7+
*/
8+
class Jetpack_3rd_Party_Domain_Mapping {
49

510
/**
6-
* Class Jetpack_3rd_Party_Domain_Mapping
11+
* @var Jetpack_3rd_Party_Domain_Mapping
12+
**/
13+
private static $instance = null;
14+
15+
/**
16+
* An array of methods that are used to hook the Jetpack sync filters for home_url and site_url to a mapping plugin.
717
*
8-
* This class contains methods that are used to provide compatibility between Jetpack sync and domain mapping plugins.
18+
* @var array
19+
*/
20+
const TEST_METHODS = array(
21+
'hook_wordpress_mu_domain_mapping',
22+
'hook_wpmu_dev_domain_mapping'
23+
);
24+
25+
static function init() {
26+
if ( is_null( self::$instance ) ) {
27+
self::$instance = new Jetpack_3rd_Party_Domain_Mapping;
28+
}
29+
30+
return self::$instance;
31+
}
32+
33+
private function __construct() {
34+
add_action( 'plugins_loaded', array( $this, 'attempt_to_hook_domain_mapping_plugins' ) );
35+
}
36+
37+
/**
38+
* This function is called on the plugins_loaded action and will loop through the TEST_METHODS
39+
* to try and hook a domain mapping plugin to the Jetpack sync filters for the home_url and site_url callables.
940
*/
10-
class Jetpack_3rd_Party_Domain_Mapping {
11-
12-
/**
13-
* This method will test for a constant and function that are known to be used with Donncha's WordPress MU
14-
* Domain Mapping plugin. If conditions are met, we hook the domain_mapping_siteurl() function to Jetpack sync
15-
* filters for home_url and site_url callables.
16-
*
17-
* @return bool
18-
*/
19-
static function hook_wordpress_mu_domain_mapping() {
20-
if ( ! Jetpack_Constants::is_defined( 'DOMAIN_MAPPING' ) || function_exists( 'domain_mapping_siteurl' ) ) {
21-
return false;
22-
}
23-
24-
add_filter( 'jetpack_sync_home_url', 'domain_mapping_siteurl' );
25-
add_filter( 'jetpack_sync_site_url', 'domain_mapping_siteurl' );
26-
27-
return true;
41+
function attempt_to_hook_domain_mapping_plugins() {
42+
if ( ! Jetpack_Constants::is_defined( 'SUNRISE' ) ) {
43+
return;
2844
}
2945

30-
/**
31-
* This method will test for a class and method known to be used in WPMU Dev's domain mapping plugin. If the
32-
* method exists, then we'll hook the swap_to_mapped_url() to our Jetpack sync fitlers for home_url and site_url.
33-
*
34-
* @return bool
35-
*/
36-
static function hook_wpmu_dev_domain_mapping() {
37-
if ( ! class_exists( 'domain_map' ) || ! method_exists( 'domain_map', 'utils' ) ) {
38-
return false;
39-
}
40-
41-
$utils = domain_map::utils();
42-
add_filter( 'jetpack_sync_home_url', array( $utils, 'swap_to_mapped_url' ) );
43-
add_filter( 'jetpack_sync_site_url', array( $utils, 'swap_to_mapped_url' ) );
44-
45-
return true;
46+
$hooked = false;
47+
$count = count( self::TEST_METHODS );
48+
for ( $i = 0; $i < $count && ! $hooked; $i++ ) {
49+
$hooked = call_user_func( array( $this, self::TEST_METHODS[ $i ] ) );
4650
}
4751
}
4852

4953
/**
50-
* This function is called on the plugins_loaded action and will loop through the methods of
51-
* Jetpack_3rd_Party_Domain_Mapping to try and hook a domain mapping plugin to the Jetpack sync
52-
* filters for the home_url and site_url callables.
54+
* This method will test for a constant and function that are known to be used with Donncha's WordPress MU
55+
* Domain Mapping plugin. If conditions are met, we hook the domain_mapping_siteurl() function to Jetpack sync
56+
* filters for home_url and site_url callables.
57+
*
58+
* @return bool
59+
*/
60+
function hook_wordpress_mu_domain_mapping() {
61+
if ( ! Jetpack_Constants::is_defined( 'DOMAIN_MAPPING' ) || ! $this->function_exists( 'domain_mapping_siteurl' ) ) {
62+
return false;
63+
}
64+
65+
add_filter( 'jetpack_sync_home_url', 'domain_mapping_siteurl' );
66+
add_filter( 'jetpack_sync_site_url', 'domain_mapping_siteurl' );
67+
68+
return true;
69+
}
70+
71+
/**
72+
* This method will test for a class and method known to be used in WPMU Dev's domain mapping plugin. If the
73+
* method exists, then we'll hook the swap_to_mapped_url() to our Jetpack sync filters for home_url and site_url.
74+
*
75+
* @return bool
76+
*/
77+
function hook_wpmu_dev_domain_mapping() {
78+
if ( ! $this->class_exists( 'domain_map' ) || ! $this->method_exists( 'domain_map', 'utils' ) ) {
79+
return false;
80+
}
81+
82+
$utils = $this->get_domain_mapping_utils_instance();
83+
add_filter( 'jetpack_sync_home_url', array( $utils, 'swap_to_mapped_url' ) );
84+
add_filter( 'jetpack_sync_site_url', array( $utils, 'swap_to_mapped_url' ) );
85+
86+
return true;
87+
}
88+
89+
/*
90+
* Utility Methods
91+
*
92+
* These methods are very minimal, and in most cases, simply pass on arguments. Why create them you ask?
93+
* So that we can test.
5394
*/
54-
function jetpack_domain_mapping_hook_compatible_plugins() {
55-
$methods = get_class_methods( 'Jetpack_3rd_Party_Domain_Mapping' );
56-
do {
57-
$method = array_pop( $methods );
58-
$hooked = call_user_func( 'Jetpack_3rd_Party_Domain_Mapping', $method );
59-
} while( ! $hooked && ! empty( $methods ) );
60-
}
61-
add_action( 'plugins_loaded', 'jetpack_domain_mapping_hook_compatible_plugins' );
62-
endif;
95+
96+
public function method_exists( $class, $method ) {
97+
return method_exists( $class, $method );
98+
}
99+
100+
public function class_exists( $class ) {
101+
return class_exists( $class );
102+
}
103+
104+
public function function_exists( $function ) {
105+
return function_exists( $function );
106+
}
107+
108+
public function get_domain_mapping_utils_instance() {
109+
return domain_map::utils();
110+
}
111+
}
112+
113+
Jetpack_3rd_Party_Domain_Mapping::init();

phpunit.xml.dist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@
7070
<testsuite name="idc">
7171
<file>tests/php/test_class.jetpack-idc.php</file>
7272
</testsuite>
73+
<testsuite name="3rd-party">
74+
<directory prefix="test_" suffix=".php">tests/php/3rd-party</directory>
75+
</testsuite>
7376
</testsuites>
7477
<groups>
7578
<exclude>
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
3+
require_once JETPACK__PLUGIN_DIR . '3rd-party/domain-mapping.php';
4+
5+
// Extend with a public constructor so we can test
6+
class MockDomainMapping extends Jetpack_3rd_Party_Domain_Mapping {
7+
public function __construct() {
8+
}
9+
}
10+
11+
class WP_Test_Domain_Mapping extends WP_UnitTestCase {
12+
function tearDown() {
13+
Jetpack_Constants::clear_constants();
14+
foreach ( $this->get_jetpack_sync_filters() as $filter ) {
15+
remove_all_filters( $filter );
16+
}
17+
}
18+
19+
function test_domain_mapping_should_not_try_to_hook_when_sunrise_disable() {
20+
$stub = $this->getMockBuilder( 'MockDomainMapping' )
21+
->setMethods( array( 'hook_wordpress_mu_domain_mapping', 'hook_wpmu_dev_domain_mapping' ) )
22+
->disableOriginalConstructor()
23+
->getMock();
24+
25+
// Both of these methods should not be called
26+
$stub->expects( $this->exactly( 0 ) )
27+
->method( 'hook_wordpress_mu_domain_mapping' )
28+
->will( $this->returnValue( false ) );
29+
30+
$stub->expects( $this->exactly( 0 ) )
31+
->method( 'hook_wpmu_dev_domain_mapping' )
32+
->will( $this->returnValue( false ) );
33+
34+
$stub->attempt_to_hook_domain_mapping_plugins();
35+
}
36+
37+
function test_domain_mapping_should_stop_search_after_hooking_once() {
38+
Jetpack_Constants::set_constant( 'SUNRISE', true );
39+
40+
$stub = $this->getMockBuilder( 'MockDomainMapping' )
41+
->setMethods( array( 'hook_wordpress_mu_domain_mapping', 'hook_wpmu_dev_domain_mapping' ) )
42+
->disableOriginalConstructor()
43+
->getMock();
44+
45+
// The first method in the array should be the only one called.
46+
$stub->expects( $this->exactly( 1 ) )
47+
->method( 'hook_wordpress_mu_domain_mapping' )
48+
->will( $this->returnValue( true ) );
49+
50+
$stub->expects( $this->exactly( 0 ) )
51+
->method( 'hook_wpmu_dev_domain_mapping' )
52+
->will( $this->returnValue( false ) );
53+
54+
$stub->attempt_to_hook_domain_mapping_plugins();
55+
}
56+
57+
function test_domain_mapping_mu_domain_mapping_not_hooked_when_function_not_exists() {
58+
Jetpack_Constants::set_constant( 'DOMAIN_MAPPING', true );
59+
60+
$stub = $this->getMockBuilder( 'MockDomainMapping' )
61+
->setMethods( array( 'function_exists' ) )
62+
->disableOriginalConstructor()
63+
->getMock();
64+
65+
$stub->expects( $this->once() )
66+
->method( 'function_exists' )
67+
->will( $this->returnValue( false ) );
68+
69+
$this->assertFalse( $stub->hook_wordpress_mu_domain_mapping() );
70+
71+
foreach ( $this->get_jetpack_sync_filters() as $filter ) {
72+
$this->assertFalse( $this->filter_has_hook( $filter ) );
73+
}
74+
}
75+
76+
function test_domain_mapping_mu_domain_mapping_hooked_when_function_exists() {
77+
Jetpack_Constants::set_constant( 'DOMAIN_MAPPING', true );
78+
79+
$stub = $this->getMockBuilder( 'MockDomainMapping' )
80+
->setMethods( array( 'function_exists' ) )
81+
->disableOriginalConstructor()
82+
->getMock();
83+
84+
$stub->expects( $this->once() )
85+
->method( 'function_exists' )
86+
->will( $this->returnValue( true ) );
87+
88+
$this->assertTrue( $stub->hook_wordpress_mu_domain_mapping() );
89+
90+
foreach ( $this->get_jetpack_sync_filters() as $filter ) {
91+
$this->assertTrue( $this->filter_has_hook( $filter ) );
92+
}
93+
}
94+
95+
function test_domain_mapping_wpmu_dev_domain_mapping_not_hooked_when_functions_not_exist() {
96+
$stub = $this->getMockBuilder( 'MockDomainMapping' )
97+
->setMethods( array( 'class_exists', 'method_exists' ) )
98+
->disableOriginalConstructor()
99+
->getMock();
100+
101+
$stub->expects( $this->once() )
102+
->method( 'class_exists' )
103+
->will( $this->returnValue( false ) );
104+
105+
$stub->expects( $this->exactly( 0 ) )
106+
->method( 'method_exists' )
107+
->will( $this->returnValue( false ) );
108+
109+
$this->assertFalse( $stub->hook_wpmu_dev_domain_mapping() );
110+
111+
foreach ( $this->get_jetpack_sync_filters() as $filter ) {
112+
$this->assertFalse( $this->filter_has_hook( $filter ) );
113+
}
114+
}
115+
116+
function test_domain_mapping_wpmu_dev_domain_mapping_hooked_when_functions_exist() {
117+
$stub = $this->getMockBuilder( 'MockDomainMapping' )
118+
->setMethods( array( 'class_exists', 'method_exists', 'get_domain_mapping_utils_instance' ) )
119+
->disableOriginalConstructor()
120+
->getMock();
121+
122+
$stub->expects( $this->once() )
123+
->method( 'class_exists' )
124+
->will( $this->returnValue( true ) );
125+
126+
$stub->expects( $this->once() )
127+
->method( 'method_exists' )
128+
->will( $this->returnValue( true ) );
129+
130+
$stub->expects( $this->once() )
131+
->method( 'get_domain_mapping_utils_instance' )
132+
->will( $this->returnValue( new stdClass() ) );
133+
134+
$this->assertTrue( $stub->hook_wpmu_dev_domain_mapping() );
135+
136+
foreach ( $this->get_jetpack_sync_filters() as $filter ) {
137+
$this->assertTrue( $this->filter_has_hook( $filter ) );
138+
}
139+
}
140+
141+
function filter_has_hook( $hook ) {
142+
global $wp_filter;
143+
return isset( $wp_filter[ $hook ] ) && ! empty( $wp_filter[ $hook ] );
144+
}
145+
146+
function get_jetpack_sync_filters() {
147+
return array(
148+
'jetpack_sync_home_url',
149+
'jetpack_sync_site_url',
150+
);
151+
}
152+
}

0 commit comments

Comments
 (0)