Make WordPress Core


Ignore:
Timestamp:
10/14/2020 06:17:55 PM (4 years ago)
Author:
iandunn
Message:

Community Events: Trim events by Unix timestamp for accuracy.

The date and end_date fields are WP timestamps representing the venue's local time. As of meta:changeset:10270 (#meta4480), new start_unix_timestamp and end_unix_timestamp values are available, providing a proper Unix timestamp in the UTC timezone. Using those is more precise, and removes the time window where the event has expired but still appears in the Events Widget.

To simplify the function, it now only accepts and returns the events themselves, rather than the entire response body.

See #51130
See #meta4480
Related: https://make.wordpress.org/core/2019/09/23/date-time-improvements-wp-5-3/

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/admin/includesCommunityEvents.php

    r48939 r49145  
    154154    /**
    155155     * Test: With a valid response, get_events() should return an associative array containing a location array and
    156      * an events array with individual events that have formatted time and date.
     156     * an events array with individual events that have Unix start/end timestamps.
    157157     *
    158158     * @since 4.8.0
     
    165165        $this->assertNotWPError( $response );
    166166        $this->assertSameSetsWithIndex( $this->get_user_location(), $response['location'] );
    167         $this->assertSame( gmdate( 'l, M j, Y', strtotime( 'next Sunday 1pm' ) ), $response['events'][0]['formatted_date'] );
    168         $this->assertSame( '1:00 pm', $response['events'][0]['formatted_time'] );
     167        $this->assertSame( strtotime( 'next Sunday 1pm' ), $response['events'][0]['start_unix_timestamp'] );
     168        $this->assertSame( strtotime( 'next Sunday 2pm' ), $response['events'][0]['end_unix_timestamp'] );
    169169
    170170        remove_filter( 'pre_http_request', array( $this, '_http_request_valid_response' ) );
     
    172172
    173173    /**
    174      * Test: get_cached_events() should return the same data as get_events(), including formatted time
    175      * and date values for each event.
     174     * Test: `get_cached_events()` should return the same data as get_events(), including Unix start/end
     175     * timestamps for each event.
    176176     *
    177177     * @since 4.8.0
     
    186186        $this->assertNotWPError( $cached_events );
    187187        $this->assertSameSetsWithIndex( $this->get_user_location(), $cached_events['location'] );
    188         $this->assertSame( gmdate( 'l, M j, Y', strtotime( 'next Sunday 1pm' ) ), $cached_events['events'][0]['formatted_date'] );
    189         $this->assertSame( '1:00 pm', $cached_events['events'][0]['formatted_time'] );
     188        $this->assertSame( strtotime( 'next Sunday 1pm' ), $cached_events['events'][0]['start_unix_timestamp'] );
     189        $this->assertSame( strtotime( 'next Sunday 2pm' ), $cached_events['events'][0]['end_unix_timestamp'] );
    190190
    191191        remove_filter( 'pre_http_request', array( $this, '_http_request_valid_response' ) );
     
    205205                array(
    206206                    'location' => $this->get_user_location(),
    207                     'events'   => array(
     207                    'events'   => $this->get_valid_events(),
     208                )
     209            ),
     210            'response' => array(
     211                'code' => 200,
     212            ),
     213            'cookies'  => '',
     214            'filename' => '',
     215        );
     216    }
     217
     218    /**
     219     * Get a sample of valid events.
     220     *
     221     * @return array[]
     222     */
     223    protected function get_valid_events() {
     224        return array(
     225            array(
     226                'type'                 => 'meetup',
     227                'title'                => 'Flexbox + CSS Grid: Magic for Responsive Layouts',
     228                'url'                  => 'https://www.meetup.com/Eastbay-WordPress-Meetup/events/236031233/',
     229                'meetup'               => 'The East Bay WordPress Meetup Group',
     230                'meetup_url'           => 'https://www.meetup.com/Eastbay-WordPress-Meetup/',
     231                'start_unix_timestamp' => strtotime( 'next Sunday 1pm' ),
     232                'end_unix_timestamp'   => strtotime( 'next Sunday 2pm' ),
     233
     234                'location'             => array(
     235                    'location'  => 'Oakland, CA, USA',
     236                    'country'   => 'us',
     237                    'latitude'  => 37.808453,
     238                    'longitude' => -122.26593,
     239                ),
     240            ),
     241
     242            array(
     243                'type'                 => 'meetup',
     244                'title'                => 'Part 3- Site Maintenance - Tools to Make It Easy',
     245                'url'                  => 'https://www.meetup.com/Wordpress-Bay-Area-CA-Foothills/events/237706839/',
     246                'meetup'               => 'WordPress Bay Area Foothills Group',
     247                'meetup_url'           => 'https://www.meetup.com/Wordpress-Bay-Area-CA-Foothills/',
     248                'start_unix_timestamp' => strtotime( 'next Wednesday 1:30pm' ),
     249                'end_unix_timestamp'   => strtotime( 'next Wednesday 2:30pm' ),
     250
     251                'location'             => array(
     252                    'location'  => 'Milpitas, CA, USA',
     253                    'country'   => 'us',
     254                    'latitude'  => 37.432813,
     255                    'longitude' => -121.907095,
     256                ),
     257            ),
     258
     259            array(
     260                'type'                 => 'wordcamp',
     261                'title'                => 'WordCamp San Francisco',
     262                'url'                  => 'https://sf.wordcamp.org/2020/',
     263                'meetup'               => null,
     264                'meetup_url'           => null,
     265                'start_unix_timestamp' => strtotime( 'next Saturday' ),
     266                'end_unix_timestamp'   => strtotime( 'next Saturday 8pm' ),
     267
     268                'location'             => array(
     269                    'location'  => 'San Francisco, CA',
     270                    'country'   => 'US',
     271                    'latitude'  => 37.432813,
     272                    'longitude' => -121.907095,
     273                ),
     274            ),
     275        );
     276    }
     277
     278    /**
     279     * Test: `trim_events()` should immediately remove expired events.
     280     *
     281     * @covers WP_Community_Events::trim_events
     282     *
     283     * @since 5.6.0
     284     */
     285    public function test_trim_expired_events() {
     286        $trim_events = new ReflectionMethod( $this->instance, 'trim_events' );
     287        $trim_events->setAccessible( true );
     288
     289        $events = $this->get_valid_events();
     290
     291        // This should be removed because it's already ended.
     292        $events[0]['start_unix_timestamp'] = strtotime( '1 hour ago' );
     293        $events[0]['end_unix_timestamp']   = strtotime( '2 seconds ago' );
     294
     295        // This should remain because it hasn't ended yet.
     296        $events[1]['start_unix_timestamp'] = strtotime( '2 seconds ago' );
     297        $events[1]['end_unix_timestamp']   = strtotime( '+1 hour' );
     298
     299        $actual = $trim_events->invoke( $this->instance, $events );
     300
     301        $this->assertCount( 2, $actual );
     302        $this->assertSame( $actual[0]['title'], 'Part 3- Site Maintenance - Tools to Make It Easy' );
     303        $this->assertSame( $actual[1]['title'], 'WordCamp San Francisco' );
     304    }
     305
     306    /**
     307     * Test: get_events() should return the events with the WordCamp pinned in the prepared list.
     308     *
     309     * @covers WP_Community_Events::trim_events
     310     *
     311     * @since 4.9.7
     312     * @since 5.6.0 Tests `trim_events()` directly instead of indirectly via `get_events()`.
     313     */
     314    public function test_trim_events_pin_wordcamp() {
     315        $trim_events = new ReflectionMethod( $this->instance, 'trim_events' );
     316        $trim_events->setAccessible( true );
     317
     318        $actual = $trim_events->invoke( $this->instance, $this->_events_with_unpinned_wordcamp() );
     319
     320        /*
     321         * San Diego was at index 3 in the mock API response, but pinning puts it at index 2,
     322         * so that it remains in the list. The other events should remain unchanged.
     323         */
     324        $this->assertCount( 3, $actual );
     325        $this->assertSame( $actual[0]['title'], 'Flexbox + CSS Grid: Magic for Responsive Layouts' );
     326        $this->assertSame( $actual[1]['title'], 'Part 3- Site Maintenance - Tools to Make It Easy' );
     327        $this->assertSame( $actual[2]['title'], 'WordCamp San Diego' );
     328    }
     329
     330    /**
     331     * Simulates a scenario where a WordCamp needs to be pinned higher than it's default position.
     332     *
     333     * @since 4.9.7
     334     * @since 5.6.0 Accepts and returns only the events, rather than an entire HTTP response.
     335     *
     336     * @return array A list of mock events.
     337     */
     338    public function _events_with_unpinned_wordcamp() {
     339        return array(
    208340                        array(
    209341                            'type'       => 'meetup',
     
    212344                            'meetup'     => 'The East Bay WordPress Meetup Group',
    213345                            'meetup_url' => 'https://www.meetup.com/Eastbay-WordPress-Meetup/',
    214                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Sunday 1pm' ) ),
     346                            'start_unix_timestamp' => strtotime( 'next Monday 1pm' ),
     347                            'end_unix_timestamp'   => strtotime( 'next Monday 2pm' ),
     348
    215349                            'location'   => array(
    216350                                'location'  => 'Oakland, CA, USA',
     
    226360                            'meetup'     => 'WordPress Bay Area Foothills Group',
    227361                            'meetup_url' => 'https://www.meetup.com/Wordpress-Bay-Area-CA-Foothills/',
    228                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Wednesday 1:30pm' ) ),
     362                            'start_unix_timestamp' => strtotime( 'next Tuesday 1:30pm' ),
     363                            'end_unix_timestamp'   => strtotime( 'next Tuesday 2:30pm' ),
     364
    229365                            'location'   => array(
    230366                                'location'  => 'Milpitas, CA, USA',
     
    235371                        ),
    236372                        array(
     373                            'type'       => 'meetup',
     374                            'title'      => 'WordPress Q&A',
     375                            'url'        => 'https://www.meetup.com/sanjosewp/events/245419844/',
     376                            'meetup'     => 'The San Jose WordPress Meetup',
     377                            'meetup_url' => 'https://www.meetup.com/sanjosewp/',
     378                            'start_unix_timestamp' => strtotime( 'next Wednesday 5:30pm' ),
     379                            'end_unix_timestamp'   => strtotime( 'next Wednesday 6:30pm' ),
     380
     381                            'location'   => array(
     382                                'location'  => 'Milpitas, CA, USA',
     383                                'country'   => 'us',
     384                                'latitude'  => 37.244194,
     385                                'longitude' => -121.889313,
     386                            ),
     387                        ),
     388                        array(
    237389                            'type'       => 'wordcamp',
    238                             'title'      => 'WordCamp Kansas City',
    239                             'url'        => 'https://2017.kansascity.wordcamp.org',
     390                            'title'      => 'WordCamp San Diego',
     391                            'url'        => 'https://2018.sandiego.wordcamp.org',
    240392                            'meetup'     => null,
    241393                            'meetup_url' => null,
    242                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Saturday' ) ),
    243                             'location'   => array(
    244                                 'location'  => 'Kansas City, MO',
     394                            'start_unix_timestamp' => strtotime( 'next Thursday 9am' ),
     395                            'end_unix_timestamp'   => strtotime( 'next Thursday 10am' ),
     396
     397                            'location'   => array(
     398                                'location'  => 'San Diego, CA',
    245399                                'country'   => 'US',
    246                                 'latitude'  => 39.0392325,
    247                                 'longitude' => -94.577076,
    248                             ),
    249                         ),
    250                     ),
    251                 )
    252             ),
    253             'response' => array(
    254                 'code' => 200,
    255             ),
    256             'cookies'  => '',
    257             'filename' => '',
    258         );
    259     }
    260 
    261     /**
    262      * Test: get_events() should return the events with the WordCamp pinned in the prepared list.
     400                                'latitude'  => 32.7220419,
     401                                'longitude' => -117.1534513,
     402                            ),
     403                        ),
     404        );
     405    }
     406
     407    /**
     408     * Test: get_events() shouldn't stick an extra WordCamp when there's already one that naturally
     409     * falls into the list.
     410     *
     411     * @covers WP_Community_Events::trim_events
    263412     *
    264413     * @since 4.9.7
    265      */
    266     public function test_get_events_pin_wordcamp() {
    267         add_filter( 'pre_http_request', array( $this, '_http_request_valid_response_unpinned_wordcamp' ) );
    268 
    269         $response_body = $this->instance->get_events();
     414     * @since 5.6.0 Tests `trim_events()` directly instead of indirectly via `get_events()`.
     415     */
     416    public function test_trim_events_dont_pin_multiple_wordcamps() {
     417        $trim_events = new ReflectionMethod( $this->instance, 'trim_events' );
     418        $trim_events->setAccessible( true );
     419
     420        $actual = $trim_events->invoke( $this->instance, $this->_events_with_multiple_wordcamps() );
    270421
    271422        /*
    272          * San Diego was at position 3 in the mock API response, but pinning puts it at position 2,
    273          * so that it remains in the list. The other events should remain unchanged.
     423         * The first meetup should be removed because it's expired, while the next 3 events are selected.
     424         * WordCamp LA should not be stuck to the list, because San Diego already appears naturally.
    274425         */
    275         $this->assertCount( 3, $response_body['events'] );
    276         $this->assertSame( $response_body['events'][0]['title'], 'Flexbox + CSS Grid: Magic for Responsive Layouts' );
    277         $this->assertSame( $response_body['events'][1]['title'], 'Part 3- Site Maintenance - Tools to Make It Easy' );
    278         $this->assertSame( $response_body['events'][2]['title'], 'WordCamp San Diego' );
    279 
    280         remove_filter( 'pre_http_request', array( $this, '_http_request_valid_response_unpinned_wordcamp' ) );
     426        $this->assertCount( 3, $actual );
     427        $this->assertSame( $actual[0]['title'], 'WordCamp San Diego' );
     428        $this->assertSame( $actual[1]['title'], 'Part 3- Site Maintenance - Tools to Make It Easy' );
     429        $this->assertSame( $actual[2]['title'], 'WordPress Q&A' );
    281430    }
    282431
    283432    /**
    284433     * Simulates a valid HTTP response where a WordCamp needs to be pinned higher than it's default position.
     434     * no need to pin extra camp b/c one already exists in response
    285435     *
    286436     * @since 4.9.7
     437     * @since 5.6.0 Tests `trim_events()` directly instead of indirectly via `get_events()`.
    287438     *
    288439     * @return array A mock HTTP response.
    289440     */
    290     public function _http_request_valid_response_unpinned_wordcamp() {
    291         return array(
    292             'headers'  => '',
    293             'response' => array( 'code' => 200 ),
    294             'cookies'  => '',
    295             'filename' => '',
    296             'body'     => wp_json_encode(
    297                 array(
    298                     'location' => $this->get_user_location(),
    299                     'events'   => array(
     441    public function _events_with_multiple_wordcamps() {
     442        return array(
    300443                        array(
    301444                            'type'       => 'meetup',
     
    304447                            'meetup'     => 'The East Bay WordPress Meetup Group',
    305448                            'meetup_url' => 'https://www.meetup.com/Eastbay-WordPress-Meetup/',
    306                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Monday 1pm' ) ),
     449                            'start_unix_timestamp' => strtotime( '2 days ago' ) - HOUR_IN_SECONDS,
     450                            'end_unix_timestamp'   => strtotime( '2 days ago' ),
     451
    307452                            'location'   => array(
    308453                                'location'  => 'Oakland, CA, USA',
     
    312457                            ),
    313458                        ),
     459
     460                        array(
     461                            'type'       => 'wordcamp',
     462                            'title'      => 'WordCamp San Diego',
     463                            'url'        => 'https://2018.sandiego.wordcamp.org',
     464                            'meetup'     => null,
     465                            'meetup_url' => null,
     466                            'start_unix_timestamp' => strtotime( 'next Tuesday 9am' ),
     467                            'end_unix_timestamp'   => strtotime( 'next Tuesday 10am' ),
     468
     469                            'location'   => array(
     470                                'location'  => 'San Diego, CA',
     471                                'country'   => 'US',
     472                                'latitude'  => 32.7220419,
     473                                'longitude' => -117.1534513,
     474                            ),
     475                        ),
     476
    314477                        array(
    315478                            'type'       => 'meetup',
     
    318481                            'meetup'     => 'WordPress Bay Area Foothills Group',
    319482                            'meetup_url' => 'https://www.meetup.com/Wordpress-Bay-Area-CA-Foothills/',
    320                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Tuesday 1:30pm' ) ),
     483                            'start_unix_timestamp' => strtotime( 'next Wednesday 1:30pm' ),
     484                            'end_unix_timestamp'   => strtotime( 'next Wednesday 2:30pm' ),
     485
    321486                            'location'   => array(
    322487                                'location'  => 'Milpitas, CA, USA',
     
    326491                            ),
    327492                        ),
     493
    328494                        array(
    329495                            'type'       => 'meetup',
     
    332498                            'meetup'     => 'The San Jose WordPress Meetup',
    333499                            'meetup_url' => 'https://www.meetup.com/sanjosewp/',
    334                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Wednesday 5:30pm' ) ),
     500                            'start_unix_timestamp' => strtotime( 'next Thursday 5:30pm' ),
     501                            'end_unix_timestamp'   => strtotime( 'next Thursday 6:30pm' ),
     502
    335503                            'location'   => array(
    336504                                'location'  => 'Milpitas, CA, USA',
     
    340508                            ),
    341509                        ),
    342                         array(
    343                             'type'       => 'wordcamp',
    344                             'title'      => 'WordCamp San Diego',
    345                             'url'        => 'https://2018.sandiego.wordcamp.org',
    346                             'meetup'     => null,
    347                             'meetup_url' => null,
    348                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Thursday 9am' ) ),
    349                             'location'   => array(
    350                                 'location'  => 'San Diego, CA',
    351                                 'country'   => 'US',
    352                                 'latitude'  => 32.7220419,
    353                                 'longitude' => -117.1534513,
    354                             ),
    355                         ),
    356                     ),
    357                 )
    358             ),
    359         );
    360     }
    361 
    362     /**
    363      * Test: get_events() shouldn't stick an extra WordCamp when there's already one that naturally
    364      * falls into the list.
    365      *
    366      * @since 4.9.7
    367      */
    368     public function test_get_events_dont_pin_multiple_wordcamps() {
    369         add_filter( 'pre_http_request', array( $this, '_http_request_valid_response_multiple_wordcamps' ) );
    370 
    371         $response_body = $this->instance->get_events();
    372 
    373         /*
    374          * The first meetup should be removed because it's expired, while the next 3 events are selected.
    375          * WordCamp LA should not be stuck to the list, because San Diego already appears naturally.
    376          */
    377         $this->assertCount( 3, $response_body['events'] );
    378         $this->assertSame( $response_body['events'][0]['title'], 'WordCamp San Diego' );
    379         $this->assertSame( $response_body['events'][1]['title'], 'Part 3- Site Maintenance - Tools to Make It Easy' );
    380         $this->assertSame( $response_body['events'][2]['title'], 'WordPress Q&A' );
    381 
    382         remove_filter( 'pre_http_request', array( $this, '_http_request_valid_response_multiple_wordcamps' ) );
    383     }
    384 
    385     /**
    386      * Simulates a valid HTTP response where a WordCamp needs to be pinned higher than it's default position.
    387      * no need to pin extra camp b/c one already exists in response
    388      *
    389      * @since 4.9.7
    390      *
    391      * @return array A mock HTTP response.
    392      */
    393     public function _http_request_valid_response_multiple_wordcamps() {
    394         return array(
    395             'headers'  => '',
    396             'response' => array( 'code' => 200 ),
    397             'cookies'  => '',
    398             'filename' => '',
    399             'body'     => wp_json_encode(
    400                 array(
    401                     'location' => $this->get_user_location(),
    402                     'events'   => array(
    403                         array(
    404                             'type'       => 'meetup',
    405                             'title'      => 'Flexbox + CSS Grid: Magic for Responsive Layouts',
    406                             'url'        => 'https://www.meetup.com/Eastbay-WordPress-Meetup/events/236031233/',
    407                             'meetup'     => 'The East Bay WordPress Meetup Group',
    408                             'meetup_url' => 'https://www.meetup.com/Eastbay-WordPress-Meetup/',
    409                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( '2 days ago' ) ),
    410                             'location'   => array(
    411                                 'location'  => 'Oakland, CA, USA',
    412                                 'country'   => 'us',
    413                                 'latitude'  => 37.808453,
    414                                 'longitude' => -122.26593,
    415                             ),
    416                         ),
    417                         array(
    418                             'type'       => 'wordcamp',
    419                             'title'      => 'WordCamp San Diego',
    420                             'url'        => 'https://2018.sandiego.wordcamp.org',
    421                             'meetup'     => null,
    422                             'meetup_url' => null,
    423                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Tuesday 9am' ) ),
    424                             'location'   => array(
    425                                 'location'  => 'San Diego, CA',
    426                                 'country'   => 'US',
    427                                 'latitude'  => 32.7220419,
    428                                 'longitude' => -117.1534513,
    429                             ),
    430                         ),
    431                         array(
    432                             'type'       => 'meetup',
    433                             'title'      => 'Part 3- Site Maintenance - Tools to Make It Easy',
    434                             'url'        => 'https://www.meetup.com/Wordpress-Bay-Area-CA-Foothills/events/237706839/',
    435                             'meetup'     => 'WordPress Bay Area Foothills Group',
    436                             'meetup_url' => 'https://www.meetup.com/Wordpress-Bay-Area-CA-Foothills/',
    437                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Wednesday 1:30pm' ) ),
    438                             'location'   => array(
    439                                 'location'  => 'Milpitas, CA, USA',
    440                                 'country'   => 'us',
    441                                 'latitude'  => 37.432813,
    442                                 'longitude' => -121.907095,
    443                             ),
    444                         ),
    445                         array(
    446                             'type'       => 'meetup',
    447                             'title'      => 'WordPress Q&A',
    448                             'url'        => 'https://www.meetup.com/sanjosewp/events/245419844/',
    449                             'meetup'     => 'The San Jose WordPress Meetup',
    450                             'meetup_url' => 'https://www.meetup.com/sanjosewp/',
    451                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Thursday 5:30pm' ) ),
    452                             'location'   => array(
    453                                 'location'  => 'Milpitas, CA, USA',
    454                                 'country'   => 'us',
    455                                 'latitude'  => 37.244194,
    456                                 'longitude' => -121.889313,
    457                             ),
    458                         ),
     510
    459511                        array(
    460512                            'type'       => 'wordcamp',
     
    463515                            'meetup'     => null,
    464516                            'meetup_url' => null,
    465                             'date'       => gmdate( 'Y-m-d H:i:s', strtotime( 'next Friday 9am' ) ),
     517                            'start_unix_timestamp' => strtotime( 'next Friday 9am' ),
     518                            'end_unix_timestamp'   => strtotime( 'next Friday 10am' ),
     519
    466520                            'location'   => array(
    467521                                'location'  => 'Los Angeles, CA',
     
    471525                            ),
    472526                        ),
    473                     ),
    474                 )
    475             ),
    476527        );
    477528    }
Note: See TracChangeset for help on using the changeset viewer.