Make WordPress Core

Ticket #33932: 33932.patch

File 33932.patch, 11.7 KB (added by ronalfy, 8 years ago)

Add filter and unit tests for automatic update emails

  • src/wp-admin/includes/class-wp-upgrader.php

     
    34723472         */
    34733473        protected function send_debug_email() {
    34743474                $update_count = 0;
    3475                 foreach ( $this->update_results as $type => $updates )
     3475               
     3476                // Copy class variable to prevent hook conflicts
     3477                $update_results = $this->update_results;
     3478                foreach ( $update_results as $type => $updates )
    34763479                        $update_count += count( $updates );
    34773480
    34783481                $body = array();
     
    34813484                $body[] = sprintf( __( 'WordPress site: %s' ), network_home_url( '/' ) );
    34823485
    34833486                // Core
    3484                 if ( isset( $this->update_results['core'] ) ) {
    3485                         $result = $this->update_results['core'][0];
     3487                if ( isset( $update_results['core'] ) ) {
     3488                        $result = $update_results['core'][0];
    34863489                        if ( $result->result && ! is_wp_error( $result->result ) ) {
    34873490                                $body[] = sprintf( __( 'SUCCESS: WordPress was successfully updated to %s' ), $result->name );
    34883491                        } else {
     
    34943497
    34953498                // Plugins, Themes, Translations
    34963499                foreach ( array( 'plugin', 'theme', 'translation' ) as $type ) {
    3497                         if ( ! isset( $this->update_results[ $type ] ) )
    3498                                 continue;
    3499                         $success_items = wp_list_filter( $this->update_results[ $type ], array( 'result' => true ) );
     3500                       
     3501                        /** 
     3502                        * Filter to disable notification emails on plugins/themes/translation. 
     3503                        * 
     3504                        * By default, administrators are notified when the update offer received 
     3505                        * from WordPress.org sets a particular flag. This allows some discretion 
     3506                        * in if and when to notify. This can be used to disabe automatic
     3507                        * update notifications. 
     3508                        * 
     3509                        * This filter is only evaluated once per update 
     3510                        *. 
     3511                        * 
     3512                        * @since 4.6.0 
     3513                        * 
     3514                        * @param bool   $notify Whether the site administrator is notified. 
     3515                        * @param string $type   The type of update (plugin, theme, translation). 
     3516                        * @param object $this   WP_Automatic_Updater instance 
     3517                        */ 
     3518                        if ( ! apply_filters( 'send_update_notification_email', true, $type, $this ) ) {
     3519                                if ( isset( $update_results[ $type ] ) ) {
     3520                                        unset( $update_results[ $type ] );
     3521                                } 
     3522                        } 
     3523
     3524                        if ( ! isset( $update_results[ $type ] ) )
     3525                                continue;
     3526
     3527                        $success_items = wp_list_filter( $update_results[ $type ], array( 'result' => true ) );
    35003528                        if ( $success_items ) {
    35013529                                $messages = array(
    35023530                                        'plugin'      => __( 'The following plugins were successfully updated:' ),
     
    35093537                                        $body[] = ' * ' . sprintf( __( 'SUCCESS: %s' ), $name );
    35103538                                }
    35113539                        }
    3512                         if ( $success_items != $this->update_results[ $type ] ) {
     3540                        if ( $success_items != $update_results[ $type ] ) {
    35133541                                // Failed updates
    35143542                                $messages = array(
    35153543                                        'plugin'      => __( 'The following plugins failed to update:' ),
     
    35183546                                );
    35193547
    35203548                                $body[] = $messages[ $type ];
    3521                                 foreach ( $this->update_results[ $type ] as $item ) {
     3549                                foreach ( $update_results[ $type ] as $item ) {
    35223550                                        if ( ! $item->result || is_wp_error( $item->result ) ) {
    35233551                                                $body[] = ' * ' . sprintf( __( 'FAILED: %s' ), $item->name );
    35243552                                                $failures++;
     
    35283556                        $body[] = '';
    35293557                }
    35303558
     3559                if ( empty( $update_results ) ) { 
     3560                        return;
     3561                }
     3562
    35313563                $site_title = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
    35323564                if ( $failures ) {
    35333565                        $body[] = trim( __(
     
    35543586                $body[] = '';
    35553587
    35563588                foreach ( array( 'core', 'plugin', 'theme', 'translation' ) as $type ) {
    3557                         if ( ! isset( $this->update_results[ $type ] ) )
     3589                        if ( ! isset( $update_results[ $type ] ) )
    35583590                                continue;
    3559                         foreach ( $this->update_results[ $type ] as $update ) {
     3591
     3592                        foreach ( $update_results[ $type ] as $update ) {
    35603593                                $body[] = $update->name;
    35613594                                $body[] = str_repeat( '-', strlen( $update->name ) );
    35623595                                foreach ( $update->messages as $message )
  • tests/phpunit/includes/bootstrap.php

     
    9494require dirname( __FILE__ ) . '/exceptions.php';
    9595require dirname( __FILE__ ) . '/utils.php';
    9696require dirname( __FILE__ ) . '/spy-rest-server.php';
     97require dirname( __FILE__ ) . '/mock-automatic-updater.php';
    9798
    9899/**
    99100 * A child class of the PHP test runner.
  • tests/phpunit/includes/mock-automatic-updater.php

     
     1<?php
     2require_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
     3/**
     4 * Class Mock_Automatic_Updater
     5 */
     6class Mock_Automatic_Updater extends WP_Automatic_Updater {
     7
     8        /**
     9         * Public method to allow manual trigger of the send_debug_emails method.
     10         *
     11         * @param array $update_results The results array we're faking for tests.
     12         */
     13        public function trigger_send_debug_email( $update_results ) {
     14                $this->update_results = $update_results;
     15                $this->send_debug_email();
     16        }
     17}
  • tests/phpunit/tests/mail.php

     
    1414                parent::tearDown();
    1515        }
    1616
     17        function tearDown() {
     18                parent::tearDown();
     19                unset( $GLOBALS['phpmailer']->mock_sent );
     20        }
     21
    1722        /**
    1823         * Send a mail with a 1000 char long line.
    1924         *
     
    304309                        '<p><strong>Wörld</strong></p>',
    305310                        'Content-Type: text/html'
    306311                );
     312                remove_action( 'phpmailer_init', array( $this, 'wp_mail_quoted_printable' ) );
     313                remove_action( 'phpmailer_init', array( $this, 'wp_mail_set_text_message' ) );
    307314
    308                 $this->assertNotContains( 'quoted-printable', $GLOBALS['phpmailer']->mock_sent[0]['header'] );
     315
     316                $mailer = tests_retrieve_phpmailer_instance();
     317                $this->assertNotContains( 'quoted-printable', $mailer->get_sent()->header );
    309318        }
    310319}
  • tests/phpunit/tests/upgrader/SendDebugEmail.php

     
     1<?php
     2/**
     3 * Tests for the send_debug_email method.
     4 *
     5 * @group upgrader
     6 */
     7class Tests_Upgrader_SendDebugEmail extends WP_UnitTestCase {
     8
     9
     10        /**
     11         * Lets be sure the mailer is reset before every test.
     12         */
     13        function setUp() {
     14                parent::setUp();
     15                unset( $GLOBALS['phpmailer']->mock_sent );
     16        }
     17
     18        /**
     19         * Lets be sure the mailer is reset after every test.
     20         */
     21        function tearDown() {
     22                parent::tearDown();
     23                unset( $GLOBALS['phpmailer']->mock_sent );
     24        }
     25
     26
     27        /**
     28         * Helper to return some update results
     29         * @return array
     30         */
     31        protected function update_results() {
     32                return array(
     33                        'core'        => array( (object) array( 'result' => true, 'name' => 'Unit Test : Core', 'messages' => array( 'Success' ) ) ),
     34                        'plugin'      => array( (object) array( 'result' => true, 'name' => 'Unit Test : Plugin', 'messages' => array( 'Success' ) ) ),
     35                        'theme'       => array( (object) array( 'result' => true, 'name' => 'Unit Test : Theme', 'messages' => array( 'Success' ) ) ),
     36                        'translation' => array( (object) array( 'result' => true, 'name' => 'Unit Test : Translation', 'messages' => array( 'Success' ) ) ),
     37                );
     38        }
     39
     40        /**
     41         * Helper to create the updater instance
     42         */
     43        protected function setup_and_run_send_debug_email() {
     44
     45                $upgrader = new Mock_Automatic_Updater();
     46                $upgrader->trigger_send_debug_email( $this->update_results() );
     47        }
     48
     49        /**
     50         * Baseline test to ensure that an email is sent that contains info for the 4 areas.
     51         * @ticket 33932
     52         */
     53        function test_send_debug_email_sends_emails() {
     54
     55                $this->setup_and_run_send_debug_email();
     56
     57                // Retrieve the mailer details.
     58                $mailer      = tests_retrieve_phpmailer_instance();
     59                $body        = $mailer->get_sent()->body;
     60                $core        = strpos( $body, 'Core' );
     61                $plugin      = strpos( $body, 'Plugin' );
     62                $theme       = strpos( $body, 'Theme' );
     63                $translation = strpos( $body, 'Translation' );
     64
     65                // Assertions.
     66                $this->assertNotSame( false, $core, '"Core" was not found in the body string' );
     67                $this->assertNotSame( false, $plugin, '"Plugin" was not found in the body string' );
     68                $this->assertNotSame( false, $theme, '"Theme" was not found in the body string' );
     69                $this->assertNotSame( false, $translation, '"Translation" was not found in the body string' );
     70        }
     71
     72        /**
     73         * Testing the send_update_notification_email filter
     74         *
     75         * @ticket 33932
     76         */
     77        function test_send_update_notification_email_filter_no_emails() {
     78
     79                /**
     80                 * Disable all notifications.
     81                 */
     82                add_filter( 'send_update_notification_email', '__return_false' );
     83
     84                $this->setup_and_run_send_debug_email();
     85
     86                // Retrieve the mailer details.
     87                $mailer      = tests_retrieve_phpmailer_instance();
     88                $body        = $mailer->get_sent()->body;
     89                $plugin      = strpos( $body, 'Plugin' );
     90                $theme       = strpos( $body, 'Theme' );
     91                $translation = strpos( $body, 'Translation' );
     92
     93                remove_filter( 'send_update_notification_email', '__return_false' );
     94
     95
     96                // Assertions.
     97                $this->assertSame( false, $plugin, '"Plugin" was found in the body string' );
     98                $this->assertSame( false, $theme, '"Theme" was found in the body string' );
     99                $this->assertSame( false, $translation, '"Translation" was found in the body string' );
     100        }
     101
     102
     103        /**
     104         * Testing the send_update_notification_email filter
     105         *
     106         * @dataProvider data_send_update_notification_email_filter_remove_single_type
     107         *
     108         * @ticket 33932
     109         */
     110        function test_send_update_notification_email_filter_remove_single_type( $type ) {
     111
     112                /**
     113                 * Disable all notifications.
     114                 */
     115                add_filter( 'send_update_notification_email', array( $this, "remove_{$type}_from_notifications" ), 10, 2 );
     116
     117                $this->setup_and_run_send_debug_email();
     118
     119                // Retrieve the mailer details.
     120                $mailer      = tests_retrieve_phpmailer_instance();
     121                $body        = $mailer->get_sent()->body;
     122                $$type      = strpos( $body, ucfirst( $type ) );
     123
     124                remove_filter( 'send_update_notification_email', array( $this, "remove_{$type}_from_notifications" ), 10, 2 );
     125
     126
     127                // Assertions.
     128                $this->assertSame( false, $$type, '"'.ucfirst( $type ).'" was found in the body string' );
     129        }
     130
     131
     132        /**
     133         * Data Provider.
     134         *
     135         * Passes the type of update meant to be suppressed.
     136         *
     137         * @since 4.6.0
     138         *
     139         * @return array {
     140         *     @type array {
     141         *         @type string The machine name of the type of update.
     142         *     }
     143         * }
     144         */
     145        function data_send_update_notification_email_filter_remove_single_type() {
     146                return array(
     147                        array( 'plugin' ),
     148                        array( 'theme' ),
     149                        array( 'translation' ),
     150                );
     151        }
     152
     153
     154        /**
     155         * Callback for the send_update_notification_email tests.
     156         *
     157         * @param bool   $will_send Will the email be sent.
     158         * @param string $type      The type of update.
     159         *
     160         * @return bool
     161         */
     162        function remove_plugin_from_notifications( $will_send, $type ) {
     163                return ( 'plugin' === $type ) ? false : true;
     164        }
     165
     166        /**
     167         * Callback for the send_update_notification_email tests.
     168         *
     169         * @param bool   $will_send Will the email be sent.
     170         * @param string $type      The type of update.
     171         *
     172         * @return bool
     173         */
     174        function remove_theme_from_notifications( $will_send, $type ) {
     175                return ( 'theme' === $type ) ? false : true;
     176        }
     177
     178        /**
     179         * Callback for the send_update_notification_email tests.
     180         *
     181         * @param bool   $will_send Will the email be sent.
     182         * @param string $type      The type of update.
     183         *
     184         * @return bool
     185         */
     186        function remove_translation_from_notifications( $will_send, $type ) {
     187                return ( 'translation' === $type ) ? false : true;
     188        }
     189}