WP_UnitTestCase::delete_user()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
require_once dirname(__FILE__) . '/factory.php';
4
require_once dirname(__FILE__) . '/trac.php';
5
6
/**
7
 * Defines a basic fixture to run multiple tests.
8
 *
9
 * Resets the state of the WordPress installation before and after every test.
10
 *
11
 * Includes utility functions and assertions useful for testing WordPress.
12
 *
13
 * All WordPress unit tests should inherit from this class.
14
 */
15
class WP_UnitTestCase extends PHPUnit_Framework_TestCase
16
{
17
18
    protected static $forced_tickets = array();
19
    protected $expected_deprecated = array();
20
    protected $caught_deprecated = array();
21
    protected $expected_doing_it_wrong = array();
22
    protected $caught_doing_it_wrong = array();
23
24
    protected static $hooks_saved = array();
25
    protected static $ignore_files;
26
27
    function __isset( $name ) 
28
    {
29
        return 'factory' === $name;
30
    }
31
32
    function __get( $name ) 
33
    {
34
        if ('factory' === $name ) {
35
            return self::factory();
36
        }
37
    }
38
39
    protected static function factory() 
40
    {
41
        static $factory = null;
42
        if (! $factory ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
43
            $factory = new WP_UnitTest_Factory();
44
        }
45
        return $factory;
46
    }
47
48
    public static function get_called_class() 
49
    {
50
        if (function_exists('get_called_class') ) {
51
            return get_called_class();
52
        }
53
54
        // PHP 5.2 only
55
        $backtrace = debug_backtrace();
56
        // [0] WP_UnitTestCase::get_called_class()
57
        // [1] WP_UnitTestCase::setUpBeforeClass()
58
        if ('call_user_func' ===  $backtrace[2]['function'] ) {
0 ignored issues
show
introduced by
Expected 1 space after "==="; 2 found
Loading history...
59
            return $backtrace[2]['args'][0][0];
60
        }
61
        return $backtrace[2]['class'];
62
    }
63
64 View Code Duplication
    public static function setUpBeforeClass() 
0 ignored issues
show
Coding Style introduced by
The function name setUpBeforeClass is in camel caps, but expected set_up_before_class instead as per the coding standard.
Loading history...
65
    {
66
        parent::setUpBeforeClass();
67
68
        $c = self::get_called_class();
69
        if (! method_exists($c, 'wpSetUpBeforeClass') ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
70
            self::commit_transaction();
71
            return;
72
        }
73
74
        call_user_func(array( $c, 'wpSetUpBeforeClass' ), self::factory());
75
76
        self::commit_transaction();
77
    }
78
79 View Code Duplication
    public static function tearDownAfterClass() 
0 ignored issues
show
Coding Style introduced by
The function name tearDownAfterClass is in camel caps, but expected tear_down_after_class instead as per the coding standard.
Loading history...
80
    {
81
        parent::tearDownAfterClass();
82
83
        _delete_all_data();
84
        self::flush_cache();
85
86
        $c = self::get_called_class();
87
        if (! method_exists($c, 'wpTearDownAfterClass') ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
88
            self::commit_transaction();
89
            return;
90
        }
91
92
        call_user_func(array( $c, 'wpTearDownAfterClass' ));
93
94
        self::commit_transaction();
95
    }
96
97
    function setUp() 
0 ignored issues
show
Coding Style introduced by
The function name setUp is in camel caps, but expected set_up instead as per the coding standard.
Loading history...
98
    {
99
        set_time_limit(0);
100
101
        if (! self::$ignore_files ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
102
            self::$ignore_files = $this->scan_user_uploads();
103
        }
104
105
        if (! self::$hooks_saved ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::$hooks_saved of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
introduced by
Expected 1 space before "!"; 0 found
Loading history...
106
            $this->_backup_hooks();
107
        }
108
109
        global $wpdb, $wp_rewrite;
110
        $wpdb->suppress_errors = false;
111
        $wpdb->show_errors = true;
112
        $wpdb->db_connect();
113
        ini_set('display_errors', 1);
114
        $this->clean_up_global_scope();
115
116
        /*
117
         * When running core tests, ensure that post types and taxonomies
118
         * are reset for each test. We skip this step for non-core tests,
119
         * given the large number of plugins that register post types and
120
         * taxonomies at 'init'.
121
         */
122
        if (defined('WP_RUN_CORE_TESTS') && WP_RUN_CORE_TESTS ) {
123
            $this->reset_post_types();
124
            $this->reset_taxonomies();
125
            $this->reset_post_statuses();
126
            $this->reset__SERVER();
127
128
            if ($wp_rewrite->permalink_structure ) {
129
                $this->set_permalink_structure('');
130
            }
131
        }
132
133
        $this->start_transaction();
134
        $this->expectDeprecated();
135
        add_filter('wp_die_handler', array( $this, 'get_wp_die_handler' ));
136
    }
137
138
    /**
139
     * Detect post-test failure conditions.
140
     *
141
     * We use this method to detect expectedDeprecated and expectedIncorrectUsage annotations.
142
     *
143
     * @since 4.2.0
144
     */
145
    protected function assertPostConditions() 
0 ignored issues
show
Coding Style introduced by
The function name assertPostConditions is in camel caps, but expected assert_post_conditions instead as per the coding standard.
Loading history...
146
    {
147
        $this->expectedDeprecated();
148
    }
149
150
    /**
151
     * After a test method runs, reset any state in WordPress the test method might have changed.
152
     */
153
    function tearDown() 
0 ignored issues
show
Coding Style introduced by
The function name tearDown is in camel caps, but expected tear_down instead as per the coding standard.
Loading history...
154
    {
155
        global $wpdb, $wp_query, $wp;
156
        $wpdb->query('ROLLBACK');
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
157
        if (is_multisite() ) {
158
            while ( ms_is_switched() ) {
159
                restore_current_blog();
160
            }
161
        }
162
        $wp_query = new WP_Query();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
163
        $wp = new WP();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
164
165
        // Reset globals related to the post loop and `setup_postdata()`.
166
        $post_globals = array( 'post', 'id', 'authordata', 'currentday', 'currentmonth', 'page', 'pages', 'multipage', 'more', 'numpages' );
167
        foreach ( $post_globals as $global ) {
168
            $GLOBALS[ $global ] = null;
169
        }
170
171
        remove_theme_support('html5');
172
        remove_filter('query', array( $this, '_create_temporary_tables' ));
173
        remove_filter('query', array( $this, '_drop_temporary_tables' ));
174
        remove_filter('wp_die_handler', array( $this, 'get_wp_die_handler' ));
175
        $this->_restore_hooks();
176
        wp_set_current_user(0);
177
    }
178
179
    function clean_up_global_scope() 
180
    {
181
        $_GET = array();
182
        $_POST = array();
183
        self::flush_cache();
184
    }
185
186
    /**
187
     * Unregister existing post types and register defaults.
188
     *
189
     * Run before each test in order to clean up the global scope, in case
190
     * a test forgets to unregister a post type on its own, or fails before
191
     * it has a chance to do so.
192
     */
193
    protected function reset_post_types() 
194
    {
195
        foreach ( get_post_types() as $pt ) {
196
            _unregister_post_type($pt);
197
        }
198
        create_initial_post_types();
199
    }
200
201
    /**
202
     * Unregister existing taxonomies and register defaults.
203
     *
204
     * Run before each test in order to clean up the global scope, in case
205
     * a test forgets to unregister a taxonomy on its own, or fails before
206
     * it has a chance to do so.
207
     */
208
    protected function reset_taxonomies() 
209
    {
210
        foreach ( get_taxonomies() as $tax ) {
211
            _unregister_taxonomy($tax);
212
        }
213
        create_initial_taxonomies();
214
    }
215
216
    /**
217
     * Unregister non-built-in post statuses.
218
     */
219
    protected function reset_post_statuses() 
220
    {
221
        foreach ( get_post_stati(array( '_builtin' => false )) as $post_status ) {
222
            _unregister_post_status($post_status);
223
        }
224
    }
225
226
    /**
227
     * Reset `$_SERVER` variables
228
     */
229
    protected function reset__SERVER() 
0 ignored issues
show
Coding Style introduced by
The function name reset__SERVER is in camel caps, but expected reset__s_e_r_v_e_r instead as per the coding standard.
Loading history...
230
    {
231
        tests_reset__SERVER();
232
    }
233
234
    /**
235
     * Saves the action and filter-related globals so they can be restored later.
236
     *
237
     * Stores $merged_filters, $wp_actions, $wp_current_filter, and $wp_filter
238
     * on a class variable so they can be restored on tearDown() using _restore_hooks().
239
     *
240
     * @global array $merged_filters
241
     * @global array $wp_actions
242
     * @global array $wp_current_filter
243
     * @global array $wp_filter
244
     * @return void
245
     */
246
    protected function _backup_hooks() 
247
    {
248
        $globals = array( 'wp_actions', 'wp_current_filter' );
249
        foreach ( $globals as $key ) {
250
            self::$hooks_saved[ $key ] = $GLOBALS[ $key ];
251
        }
252
        self::$hooks_saved['wp_filter'] = array();
253
        foreach ( $GLOBALS['wp_filter'] as $hook_name => $hook_object ) {
254
            self::$hooks_saved['wp_filter'][ $hook_name ] = clone $hook_object;
255
        }
256
    }
257
258
    /**
259
     * Restores the hook-related globals to their state at setUp()
260
     * so that future tests aren't affected by hooks set during this last test.
261
     *
262
     * @global array $merged_filters
263
     * @global array $wp_actions
264
     * @global array $wp_current_filter
265
     * @global array $wp_filter
266
     * @return void
267
     */
268
    protected function _restore_hooks() 
269
    {
270
        $globals = array( 'wp_actions', 'wp_current_filter' );
271
        foreach ( $globals as $key ) {
272
            if (isset(self::$hooks_saved[ $key ]) ) {
273
                $GLOBALS[ $key ] = self::$hooks_saved[ $key ];
274
            }
275
        }
276
        if (isset(self::$hooks_saved['wp_filter']) ) {
277
            $GLOBALS['wp_filter'] = array();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
278
            foreach ( self::$hooks_saved['wp_filter'] as $hook_name => $hook_object ) {
279
                $GLOBALS['wp_filter'][ $hook_name ] = clone $hook_object;
280
            }
281
        }
282
    }
283
284
    static function flush_cache() 
285
    {
286
        global $wp_object_cache;
287
        $wp_object_cache->group_ops = array();
288
        $wp_object_cache->stats = array();
289
        $wp_object_cache->memcache_debug = array();
290
        $wp_object_cache->cache = array();
291
        if (method_exists($wp_object_cache, '__remoteset') ) {
292
            $wp_object_cache->__remoteset();
293
        }
294
        wp_cache_flush();
295
        wp_cache_add_global_groups(array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache' ));
296
        wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
297
    }
298
299
    function start_transaction() 
300
    {
301
        global $wpdb;
302
        $wpdb->query('SET autocommit = 0;');
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
303
        $wpdb->query('START TRANSACTION;');
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
304
        add_filter('query', array( $this, '_create_temporary_tables' ));
305
        add_filter('query', array( $this, '_drop_temporary_tables' ));
306
    }
307
308
    /**
309
     * Commit the queries in a transaction.
310
     *
311
     * @since 4.1.0
312
     */
313
    public static function commit_transaction() 
314
    {
315
        global $wpdb;
316
        $wpdb->query('COMMIT;');
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
317
    }
318
319 View Code Duplication
    function _create_temporary_tables( $query ) 
320
    {
321
        if ('CREATE TABLE' === substr(trim($query), 0, 12) ) {
322
              return substr_replace(trim($query), 'CREATE TEMPORARY TABLE', 0, 12);
323
        }
324
        return $query;
325
    }
326
327 View Code Duplication
    function _drop_temporary_tables( $query ) 
328
    {
329
        if ('DROP TABLE' === substr(trim($query), 0, 10) ) {
330
              return substr_replace(trim($query), 'DROP TEMPORARY TABLE', 0, 10);
331
        }
332
        return $query;
333
    }
334
335
    function get_wp_die_handler( $handler ) 
336
    {
337
        return array( $this, 'wp_die_handler' );
338
    }
339
340
    function wp_die_handler( $message ) 
341
    {
342
        if (! is_scalar($message) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
343
            $message = '0';
344
        }
345
346
        throw new WPDieException($message);
347
    }
348
349
    function expectDeprecated() 
0 ignored issues
show
Coding Style introduced by
The function name expectDeprecated is in camel caps, but expected expect_deprecated instead as per the coding standard.
Loading history...
350
    {
351
        $annotations = $this->getAnnotations();
352
        foreach ( array( 'class', 'method' ) as $depth ) {
353
            if (! empty($annotations[ $depth ]['expectedDeprecated']) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
354
                $this->expected_deprecated = array_merge($this->expected_deprecated, $annotations[ $depth ]['expectedDeprecated']);
355
            }
356
            if (! empty($annotations[ $depth ]['expectedIncorrectUsage']) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
357
                $this->expected_doing_it_wrong = array_merge($this->expected_doing_it_wrong, $annotations[ $depth ]['expectedIncorrectUsage']);
358
            }
359
        }
360
        add_action('deprecated_function_run', array( $this, 'deprecated_function_run' ));
361
        add_action('deprecated_argument_run', array( $this, 'deprecated_function_run' ));
362
        add_action('deprecated_hook_run', array( $this, 'deprecated_function_run' ));
363
        add_action('doing_it_wrong_run', array( $this, 'doing_it_wrong_run' ));
364
        add_action('deprecated_function_trigger_error', '__return_false');
365
        add_action('deprecated_argument_trigger_error', '__return_false');
366
        add_action('deprecated_hook_trigger_error',     '__return_false');
367
        add_action('doing_it_wrong_trigger_error',      '__return_false');
368
    }
369
370
    function expectedDeprecated() 
0 ignored issues
show
Coding Style introduced by
The function name expectedDeprecated is in camel caps, but expected expected_deprecated instead as per the coding standard.
Loading history...
371
    {
372
        $errors = array();
373
374
        $not_caught_deprecated = array_diff($this->expected_deprecated, $this->caught_deprecated);
375
        foreach ( $not_caught_deprecated as $not_caught ) {
376
            $errors[] = "Failed to assert that $not_caught triggered a deprecated notice";
377
        }
378
379
        $unexpected_deprecated = array_diff($this->caught_deprecated, $this->expected_deprecated);
380
        foreach ( $unexpected_deprecated as $unexpected ) {
381
            $errors[] = "Unexpected deprecated notice for $unexpected";
382
        }
383
384
        $not_caught_doing_it_wrong = array_diff($this->expected_doing_it_wrong, $this->caught_doing_it_wrong);
385
        foreach ( $not_caught_doing_it_wrong as $not_caught ) {
386
            $errors[] = "Failed to assert that $not_caught triggered an incorrect usage notice";
387
        }
388
389
        $unexpected_doing_it_wrong = array_diff($this->caught_doing_it_wrong, $this->expected_doing_it_wrong);
390
        foreach ( $unexpected_doing_it_wrong as $unexpected ) {
391
            $errors[] = "Unexpected incorrect usage notice for $unexpected";
392
        }
393
394
        if (! empty($errors) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
395
            $this->fail(implode("\n", $errors));
396
        }
397
    }
398
399
    /**
400
     * Declare an expected `_deprecated_function()` or `_deprecated_argument()` call from within a test.
401
     *
402
     * @since 4.2.0
403
     *
404
     * @param string $deprecated Name of the function, method, class, or argument that is deprecated. Must match
405
     *                           first parameter of the `_deprecated_function()` or `_deprecated_argument()` call.
406
     */
407
    public function setExpectedDeprecated( $deprecated ) 
0 ignored issues
show
Coding Style introduced by
The function name setExpectedDeprecated is in camel caps, but expected set_expected_deprecated instead as per the coding standard.
Loading history...
408
    {
409
        array_push($this->expected_deprecated, $deprecated);
410
    }
411
412
    /**
413
     * Declare an expected `_doing_it_wrong()` call from within a test.
414
     *
415
     * @since 4.2.0
416
     *
417
     * @param string $deprecated Name of the function, method, or class that appears in the first argument of the
0 ignored issues
show
Bug introduced by
There is no parameter named $deprecated. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
418
     *                           source `_doing_it_wrong()` call.
419
     */
420
    public function setExpectedIncorrectUsage( $doing_it_wrong ) 
0 ignored issues
show
Coding Style introduced by
The function name setExpectedIncorrectUsage is in camel caps, but expected set_expected_incorrect_usage instead as per the coding standard.
Loading history...
421
    {
422
        array_push($this->expected_doing_it_wrong, $doing_it_wrong);
423
    }
424
425
    function deprecated_function_run( $function ) 
426
    {
427
        if (! in_array($function, $this->caught_deprecated) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
428
              $this->caught_deprecated[] = $function;
429
        }
430
    }
431
432
    function doing_it_wrong_run( $function ) 
433
    {
434
        if (! in_array($function, $this->caught_doing_it_wrong) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
435
              $this->caught_doing_it_wrong[] = $function;
436
        }
437
    }
438
439
    function assertWPError( $actual, $message = '' ) 
0 ignored issues
show
Coding Style introduced by
The function name assertWPError is in camel caps, but expected assert_w_p_error instead as per the coding standard.
Loading history...
440
    {
441
        $this->assertInstanceOf('WP_Error', $actual, $message);
442
    }
443
444
    function assertNotWPError( $actual, $message = '' ) 
0 ignored issues
show
Coding Style introduced by
The function name assertNotWPError is in camel caps, but expected assert_not_w_p_error instead as per the coding standard.
Loading history...
445
    {
446
        if (is_wp_error($actual) && '' === $message ) {
447
            $message = $actual->get_error_message();
448
        }
449
        $this->assertNotInstanceOf('WP_Error', $actual, $message);
450
    }
451
452
    function assertEqualFields( $object, $fields ) 
0 ignored issues
show
Coding Style introduced by
The function name assertEqualFields is in camel caps, but expected assert_equal_fields instead as per the coding standard.
Loading history...
453
    {
454
        foreach( $fields as $field_name => $field_value ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
455
            if ($object->$field_name != $field_value ) {
456
                $this->fail();
457
            }
458
        }
459
    }
460
461
    function assertDiscardWhitespace( $expected, $actual ) 
0 ignored issues
show
Coding Style introduced by
The function name assertDiscardWhitespace is in camel caps, but expected assert_discard_whitespace instead as per the coding standard.
Loading history...
462
    {
463
        $this->assertEquals(preg_replace('/\s*/', '', $expected), preg_replace('/\s*/', '', $actual));
464
    }
465
466
    function assertEqualSets( $expected, $actual ) 
0 ignored issues
show
Coding Style introduced by
The function name assertEqualSets is in camel caps, but expected assert_equal_sets instead as per the coding standard.
Loading history...
467
    {
468
        sort($expected);
469
        sort($actual);
470
        $this->assertEquals($expected, $actual);
471
    }
472
473
    function assertEqualSetsWithIndex( $expected, $actual ) 
0 ignored issues
show
Coding Style introduced by
The function name assertEqualSetsWithIndex is in camel caps, but expected assert_equal_sets_with_index instead as per the coding standard.
Loading history...
474
    {
475
        ksort($expected);
476
        ksort($actual);
477
        $this->assertEquals($expected, $actual);
478
    }
479
480
    /**
481
     * Modify WordPress's query internals as if a given URL has been requested.
482
     *
483
     * @param string $url The URL for the request.
484
     */
485
    function go_to( $url ) 
486
    {
487
        // note: the WP and WP_Query classes like to silently fetch parameters
488
        // from all over the place (globals, GET, etc), which makes it tricky
489
        // to run them more than once without very carefully clearing everything
490
        $_GET = $_POST = array();
491
        foreach (array('query_string', 'id', 'postdata', 'authordata', 'day', 'currentmonth', 'page', 'pages', 'multipage', 'more', 'numpages', 'pagenow') as $v) {
0 ignored issues
show
introduced by
No space before closing parenthesis is prohibited
Loading history...
492
            if (isset($GLOBALS[$v]) ) {
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
493
                unset($GLOBALS[$v]);
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
494
            }
495
        }
496
        $parts = parse_url($url);
497
        if (isset($parts['scheme'])) {
0 ignored issues
show
introduced by
No space before closing parenthesis is prohibited
Loading history...
498
            $req = isset($parts['path']) ? $parts['path'] : '';
499
            if (isset($parts['query'])) {
0 ignored issues
show
introduced by
No space before closing parenthesis is prohibited
Loading history...
500
                $req .= '?' . $parts['query'];
501
                // parse the url query vars into $_GET
502
                parse_str($parts['query'], $_GET);
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
503
            }
504
        } else {
505
            $req = $url;
506
        }
507
        if (! isset($parts['query']) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
508
            $parts['query'] = '';
509
        }
510
511
        $_SERVER['REQUEST_URI'] = $req;
512
        unset($_SERVER['PATH_INFO']);
513
514
        self::flush_cache();
515
        unset($GLOBALS['wp_query'], $GLOBALS['wp_the_query']);
516
        $GLOBALS['wp_the_query'] = new WP_Query();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
517
        $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
518
519
        $public_query_vars  = $GLOBALS['wp']->public_query_vars;
520
        $private_query_vars = $GLOBALS['wp']->private_query_vars;
521
522
        $GLOBALS['wp'] = new WP();
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
523
        $GLOBALS['wp']->public_query_vars  = $public_query_vars;
524
        $GLOBALS['wp']->private_query_vars = $private_query_vars;
525
526
        _cleanup_query_vars();
527
528
        $GLOBALS['wp']->main($parts['query']);
529
    }
530
531
    protected function checkRequirements() 
0 ignored issues
show
Coding Style introduced by
The function name checkRequirements is in camel caps, but expected check_requirements instead as per the coding standard.
Loading history...
532
    {
533
        parent::checkRequirements();
534
535
        // Core tests no longer check against open Trac tickets, but others using WP_UnitTestCase may do so.
536
        if (defined('WP_RUN_CORE_TESTS') && WP_RUN_CORE_TESTS ) {
537
            return;
538
        }
539
540
        if (WP_TESTS_FORCE_KNOWN_BUGS ) {
541
              return;
542
        }
543
        $tickets = PHPUnit_Util_Test::getTickets(get_class($this), $this->getName(false));
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
544
        foreach ( $tickets as $ticket ) {
545
            if (is_numeric($ticket) ) {
546
                $this->knownWPBug($ticket);
547
            } elseif ('UT' == substr($ticket, 0, 2) ) {
548
                $ticket = substr($ticket, 2);
549
                if ($ticket && is_numeric($ticket) ) {
550
                     $this->knownUTBug($ticket);
551
                }
552
            } elseif ('Plugin' == substr($ticket, 0, 6) ) {
553
                $ticket = substr($ticket, 6);
554
                if ($ticket && is_numeric($ticket) ) {
555
                     $this->knownPluginBug($ticket);
556
                }
557
            }
558
        }
559
    }
560
561
    /**
562
     * Skips the current test if there is an open WordPress ticket with id $ticket_id
563
     */
564 View Code Duplication
    function knownWPBug( $ticket_id ) 
0 ignored issues
show
Coding Style introduced by
The function name knownWPBug is in camel caps, but expected known_w_p_bug instead as per the coding standard.
Loading history...
565
    {
566
        if (WP_TESTS_FORCE_KNOWN_BUGS || in_array($ticket_id, self::$forced_tickets) ) {
567
              return;
568
        }
569
        if (! TracTickets::isTracTicketClosed('https://core.trac.wordpress.org', $ticket_id) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression \TracTickets::isTracTick...press.org', $ticket_id) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
introduced by
Expected 1 space before "!"; 0 found
Loading history...
570
              $this->markTestSkipped(sprintf('WordPress Ticket #%d is not fixed', $ticket_id));
571
        }
572
    }
573
574
    /**
575
     * Skips the current test if there is an open unit tests ticket with id $ticket_id
576
     */
577 View Code Duplication
    function knownUTBug( $ticket_id ) 
0 ignored issues
show
Coding Style introduced by
The function name knownUTBug is in camel caps, but expected known_u_t_bug instead as per the coding standard.
Loading history...
578
    {
579
        if (WP_TESTS_FORCE_KNOWN_BUGS || in_array('UT' . $ticket_id, self::$forced_tickets) ) {
580
              return;
581
        }
582
        if (! TracTickets::isTracTicketClosed('https://unit-tests.trac.wordpress.org', $ticket_id) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression \TracTickets::isTracTick...press.org', $ticket_id) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
introduced by
Expected 1 space before "!"; 0 found
Loading history...
583
              $this->markTestSkipped(sprintf('Unit Tests Ticket #%d is not fixed', $ticket_id));
584
        }
585
    }
586
587
    /**
588
     * Skips the current test if there is an open plugin ticket with id $ticket_id
589
     */
590 View Code Duplication
    function knownPluginBug( $ticket_id ) 
0 ignored issues
show
Coding Style introduced by
The function name knownPluginBug is in camel caps, but expected known_plugin_bug instead as per the coding standard.
Loading history...
591
    {
592
        if (WP_TESTS_FORCE_KNOWN_BUGS || in_array('Plugin' . $ticket_id, self::$forced_tickets) ) {
593
              return;
594
        }
595
        if (! TracTickets::isTracTicketClosed('https://plugins.trac.wordpress.org', $ticket_id) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression \TracTickets::isTracTick...press.org', $ticket_id) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
introduced by
Expected 1 space before "!"; 0 found
Loading history...
596
              $this->markTestSkipped(sprintf('WordPress Plugin Ticket #%d is not fixed', $ticket_id));
597
        }
598
    }
599
600
    public static function forceTicket( $ticket ) 
0 ignored issues
show
Coding Style introduced by
The function name forceTicket is in camel caps, but expected force_ticket instead as per the coding standard.
Loading history...
601
    {
602
        self::$forced_tickets[] = $ticket;
603
    }
604
605
    /**
606
     * Define constants after including files.
607
     */
608
    function prepareTemplate( Text_Template $template ) 
0 ignored issues
show
Coding Style introduced by
The function name prepareTemplate is in camel caps, but expected prepare_template instead as per the coding standard.
Loading history...
609
    {
610
        $template->setVar(array( 'constants' => '' ));
611
        $template->setVar(array( 'wp_constants' => PHPUnit_Util_GlobalState::getConstantsAsString() ));
612
        parent::prepareTemplate($template);
613
    }
614
615
    /**
616
     * Returns the name of a temporary file
617
     */
618
    function temp_filename() 
619
    {
620
        $tmp_dir = '';
621
        $dirs = array( 'TMP', 'TMPDIR', 'TEMP' );
622
        foreach( $dirs as $dir ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
623
            if (isset($_ENV[$dir]) && !empty($_ENV[$dir]) ) {
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
introduced by
Expected 1 space after "!"; 0 found
Loading history...
624
                $tmp_dir = $dir;
625
            }
626
             break;
627
        }
628
        if (empty($tmp_dir) ) {
629
            $tmp_dir = '/tmp';
630
        }
631
        $tmp_dir = realpath($tmp_dir);
632
        return tempnam($tmp_dir, 'wpunit');
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using tempnam()
Loading history...
633
    }
634
635
    /**
636
     * Check each of the WP_Query is_* functions/properties against expected boolean value.
637
     *
638
     * Any properties that are listed by name as parameters will be expected to be true; any others are
639
     * expected to be false. For example, assertQueryTrue('is_single', 'is_feed') means is_single()
640
     * and is_feed() must be true and everything else must be false to pass.
641
     *
642
     * @param string $prop,... Any number of WP_Query properties that are expected to be true for the current request.
0 ignored issues
show
Bug introduced by
There is no parameter named $prop,.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
643
     */
644
    function assertQueryTrue(/* ... */) 
0 ignored issues
show
Coding Style introduced by
The function name assertQueryTrue is in camel caps, but expected assert_query_true instead as per the coding standard.
Loading history...
645
    {
646
        global $wp_query;
647
        $all = array(
648
         'is_404',
649
         'is_admin',
650
         'is_archive',
651
         'is_attachment',
652
         'is_author',
653
         'is_category',
654
         'is_comment_feed',
655
         'is_date',
656
         'is_day',
657
         'is_embed',
658
         'is_feed',
659
         'is_front_page',
660
         'is_home',
661
         'is_month',
662
         'is_page',
663
         'is_paged',
664
         'is_post_type_archive',
665
         'is_posts_page',
666
         'is_preview',
667
         'is_robots',
668
         'is_search',
669
         'is_single',
670
         'is_singular',
671
         'is_tag',
672
         'is_tax',
673
         'is_time',
674
         'is_trackback',
675
         'is_year',
676
        );
677
        $true = func_get_args();
678
679
        foreach ( $true as $true_thing ) {
680
               $this->assertContains($true_thing, $all, "{$true_thing}() is not handled by assertQueryTrue().");
681
        }
682
683
        $passed = true;
684
        $not_false = $not_true = array(); // properties that were not set to expected values
685
686
        foreach ( $all as $query_thing ) {
687
             $result = is_callable($query_thing) ? call_user_func($query_thing) : $wp_query->$query_thing;
688
689
            if (in_array($query_thing, $true) ) {
690
                if (! $result ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
691
                    array_push($not_true, $query_thing);
692
                    $passed = false;
693
                }
694
            } else if ($result ) {
695
                array_push($not_false, $query_thing);
696
                $passed = false;
697
            }
698
        }
699
700
        $message = '';
701
        if (count($not_true) ) {
702
               $message .= implode($not_true, ', ') . ' is expected to be true. ';
703
        }
704
        if (count($not_false) ) {
705
               $message .= implode($not_false, ', ') . ' is expected to be false.';
706
        }
707
        $this->assertTrue($passed, $message);
708
    }
709
710
    function unlink( $file ) 
711
    {
712
        $exists = is_file($file);
713
        if ($exists && ! in_array($file, self::$ignore_files) ) {
714
            //error_log( $file );
715
            unlink($file);
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using unlink()
Loading history...
716
        } elseif (! $exists ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
717
            $this->fail("Trying to delete a file that doesn't exist: $file");
718
        }
719
    }
720
721
    function rmdir( $path ) 
722
    {
723
        $files = $this->files_in_dir($path);
724
        foreach ( $files as $file ) {
725
            if (! in_array($file, self::$ignore_files) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
726
                $this->unlink($file);
727
            }
728
        }
729
    }
730
731
    function remove_added_uploads() 
732
    {
733
        // Remove all uploads.
734
        $uploads = wp_upload_dir();
735
        $this->rmdir($uploads['basedir']);
736
    }
737
738
    function files_in_dir( $dir ) 
739
    {
740
        $files = array();
741
742
        $iterator = new RecursiveDirectoryIterator($dir);
743
        $objects = new RecursiveIteratorIterator($iterator);
744
        foreach ( $objects as $name => $object ) {
745
            if (is_file($name) ) {
746
                $files[] = $name;
747
            }
748
        }
749
750
        return $files;
751
    }
752
753
    function scan_user_uploads() 
754
    {
755
        static $files = array();
756
        if (! empty($files) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
757
            return $files;
758
        }
759
760
        $uploads = wp_upload_dir();
761
        $files = $this->files_in_dir($uploads['basedir']);
762
        return $files;
763
    }
764
765
    function delete_folders( $path ) 
766
    {
767
        $this->matched_dirs = array();
768
        if (! is_dir($path) ) {
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
769
            return;
770
        }
771
772
        $this->scandir($path);
773
        foreach ( array_reverse($this->matched_dirs) as $dir ) {
774
            rmdir($dir);
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using rmdir()
Loading history...
775
        }
776
        rmdir($path);
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using rmdir()
Loading history...
777
    }
778
779
    function scandir( $dir ) 
780
    {
781
        foreach ( scandir($dir) as $path ) {
782
            if (0 !== strpos($path, '.') && is_dir($dir . '/' . $path) ) {
783
                $this->matched_dirs[] = $dir . '/' . $path;
784
                $this->scandir($dir . '/' . $path);
785
            }
786
        }
787
    }
788
789
    /**
790
     * Helper to Convert a microtime string into a float
791
     */
792
    protected function _microtime_to_float($microtime )
793
    {
794
        $time_array = explode(' ', $microtime);
795
        return array_sum($time_array);
796
    }
797
798
    /**
799
     * Multisite-agnostic way to delete a user from the database.
800
     *
801
     * @since 4.3.0
802
     */
803
    public static function delete_user( $user_id ) 
804
    {
805
        if (is_multisite() ) {
806
            return wpmu_delete_user($user_id);
807
        } else {
808
            return wp_delete_user($user_id);
809
        }
810
    }
811
812
    /**
813
     * Utility method that resets permalinks and flushes rewrites.
814
     *
815
     * @since 4.4.0
816
     *
817
     * @global WP_Rewrite $wp_rewrite
818
     *
819
     * @param string $structure Optional. Permalink structure to set. Default empty.
820
     */
821
    public function set_permalink_structure( $structure = '' ) 
822
    {
823
        global $wp_rewrite;
824
825
        $wp_rewrite->init();
826
        $wp_rewrite->set_permalink_structure($structure);
827
        $wp_rewrite->flush_rules();
828
    }
829
830
    function _make_attachment($upload, $parent_post_id = 0) 
831
    {
832
        $type = '';
833 View Code Duplication
        if (!empty($upload['type']) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
introduced by
Expected 1 space after "!"; 0 found
Loading history...
introduced by
Expected 1 space before "!"; 0 found
Loading history...
834
            $type = $upload['type'];
835
        } else {
836
            $mime = wp_check_filetype($upload['file']);
837
            if ($mime) {
0 ignored issues
show
introduced by
No space before closing parenthesis is prohibited
Loading history...
838
                $type = $mime['type'];
839
            }
840
        }
841
842
        $attachment = array(
843
         'post_title' => basename($upload['file']),
844
         'post_content' => '',
845
         'post_type' => 'attachment',
846
         'post_parent' => $parent_post_id,
847
         'post_mime_type' => $type,
848
         'guid' => $upload[ 'url' ],
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
849
        );
850
851
        // Save the data
852
        $id = wp_insert_attachment($attachment, $upload[ 'file' ], $parent_post_id);
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
853
        wp_update_attachment_metadata($id, wp_generate_attachment_metadata($id, $upload['file']));
854
        return $id;
855
    }
856
}
857