Making WordPress.org

Ticket #1614: 1614.2.diff

File 1614.2.diff, 13.8 KB (added by obenland, 8 years ago)
  • tests/phpunit/tests/wporg-plugin-api.php

     
     1<?php
     2
     3require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
     4
     5/**
     6 *
     7 * @group plugins-api
     8 */
     9class Tests_Plugins_API extends WP_UnitTestCase {
     10
     11        public $fields = array(
     12                'short_description' => true,
     13                'description'       => true,
     14                'sections'          => true,
     15                'tested'            => true,
     16                'requires'          => true,
     17                'rating'            => true,
     18                'ratings'           => true,
     19                'downloaded'        => true,
     20                'downloadlink'      => true,
     21                'last_updated'      => true,
     22                'added'             => true,
     23                'tags'              => true,
     24                'compatibility'     => true,
     25                'homepage'          => true,
     26                'versions'          => true,
     27                'stable_tag'        => true,
     28                'donate_link'       => true,
     29                'reviews'           => true,
     30                'banners'           => true,
     31                'icons'             => true,
     32                'active_installs'   => true,
     33                'group'             => true,
     34                'contributors'      => true,
     35        );
     36
     37        function test_wporg_plugin_api_serialize_php() {
     38                $response = wp_remote_post( 'http://api.wordpress.org/plugins/info/1.0/', array(
     39                        'timeout' => 15,
     40                        'body'    => array(
     41                                'action'  => 'plugin_information',
     42                                'request' => serialize( (object) array( 'slug' => 'jetpack', 'fields' => $this->fields ) ),
     43                        ),
     44                ) );
     45                $plugins = maybe_unserialize( wp_remote_retrieve_body( $response ) );
     46
     47                $this->_check_response_attributes( $plugins );
     48        }
     49
     50        function test_wporg_plugin_api_serialize_php_get() {
     51                $url      = add_query_arg( 'fields', implode( ',' , array_keys( $this->fields ) ), 'http://api.wordpress.org/plugins/info/1.0/jetpack.php' );
     52                $response = wp_remote_get( $url );
     53                $plugins  = maybe_unserialize( wp_remote_retrieve_body( $response ) );
     54
     55                $this->_check_response_attributes( $plugins );
     56        }
     57
     58        function test_wporg_plugin_api_xml() {
     59                $url      = add_query_arg( 'fields', implode( ',' , array_keys( $this->fields ) ), 'http://api.wordpress.org/plugins/info/1.0/jetpack.xml' );
     60                $response = wp_remote_get( $url );
     61                $plugins  = wp_remote_retrieve_body( $response );
     62
     63                // TODO: validate XML response.
     64                $this->markTestSkipped( 'Needs XML parsing.' );
     65                $this->_check_response_attributes( $plugins );
     66        }
     67
     68        function test_wporg_plugin_api_json() {
     69                $url      = add_query_arg( 'fields', implode( ',' , array_keys( $this->fields ) ), 'http://api.wordpress.org/plugins/info/1.0/jetpack.json' );
     70                $response = wp_remote_get( $url );
     71                $plugins  = (object) json_decode( wp_remote_retrieve_body( $response ), true );
     72
     73                $this->_check_response_attributes( $plugins );
     74        }
     75
     76        function test_wporg_plugin_api_1_1_json() {
     77                $response = wp_remote_post( 'http://api.wordpress.org/plugins/info/1.1/', array(
     78                        'timeout' => 15,
     79                        'body'    => array(
     80                                'action'  => 'plugin_information',
     81                                'request' => (object) array( 'slug' => 'jetpack', 'fields' => $this->fields ),
     82                        ),
     83                ) );
     84                $plugins = (object) json_decode( wp_remote_retrieve_body( $response ), true );
     85
     86                $this->_check_response_attributes( $plugins );
     87        }
     88
     89        function test_plugins_api_function_action_plugin_information() {
     90                $plugins = plugins_api( 'plugin_information', array( 'slug' => 'jetpack', 'fields' => $this->fields ) );
     91                $this->_check_response_attributes( $plugins );
     92        }
     93
     94        function test_plugins_api_function_action_query_plugins_search() {
     95                $slug     = 'hello-dolly';
     96                $per_page = 4;
     97                $page     = 2;
     98                $plugins  = plugins_api( 'query_plugins', array(
     99                        'search'   => $slug,
     100                        'per_page' => $per_page,
     101                        'page'     => $page,
     102                        'fields'   => $this->fields,
     103                ) );
     104
     105                $this->_check_response_plugin_query( $plugins, $per_page, $page );
     106
     107                // If search term exactly matches a slug, it should be returned first.
     108                $plugins  = plugins_api( 'query_plugins', array( 'search' => $slug ) );
     109                $this->assertEquals( $plugins->plugins[0]->slug, $slug );
     110        }
     111
     112        // Plugins with a specific tag.
     113        function test_plugins_api_function_action_query_plugins_tag() {
     114                $tag     = 'widget';
     115                $plugins = plugins_api( 'query_plugins', array( 'tag' => $tag, 'fields' => $this->fields ) );
     116
     117                foreach ( $plugins->plugins as $plugin ) {
     118                        $this->assertArrayHasKey( $tag, $plugin->tags, "Contains tag $tag" );
     119                }
     120                $this->_check_response_plugin_query( $plugins );
     121        }
     122
     123        // Plugins written by a specific author.
     124        function test_plugins_api_function_action_query_plugins_author() {
     125                $author  = 'wordpressdotorg';
     126                $plugins = plugins_api( 'query_plugins', array( 'author' => $author, 'fields' => $this->fields ) );
     127
     128                foreach ( $plugins->plugins as $plugin ) {
     129                        $this->assertArrayHasKey( $author, $plugin->contributors, "Contains author $author" );
     130                }
     131                $this->_check_response_plugin_query( $plugins, 1 );
     132        }
     133
     134        // Favorites.
     135        function test_plugins_api_function_action_query_plugins_user() {
     136                $plugins = plugins_api( 'query_plugins', array( 'user' => 'markjaquith', 'fields' => $this->fields ) );
     137                $this->_check_response_plugin_query( $plugins, 1 );
     138        }
     139
     140        function test_plugins_api_function_action_query_plugins_browse() {
     141                $plugins = plugins_api( 'query_plugins', array( 'browse' => 'popular', 'fields' => $this->fields ) );
     142                $this->_check_response_plugin_query( $plugins );
     143        }
     144
     145        function test_plugins_api_function_action_query_plugins_installed_plugins() {
     146                $plugins = plugins_api( 'query_plugins', array( 'installed_plugins' => array( 'jetpack' ), 'fields' => $this->fields ) );
     147                $this->_check_response_plugin_query( $plugins, 1 );
     148        }
     149
     150        function test_plugins_api_function_action_query_plugins_local() {
     151                // Not yet implemented. Shouldn't change the structure of the response though.
     152                $plugins = plugins_api( 'query_plugins', array( 'local' => 'hello', 'fields' => $this->fields ) );
     153                $this->_check_response_plugin_query( $plugins, 1 );
     154        }
     155
     156        function test_plugins_api_function_action_hot_categories() {
     157                $number  = 2;
     158                $plugins = plugins_api( 'hot_categories', array( 'number' => $number ) );
     159
     160                $this->assertEquals( $number, count( $plugins ) );
     161                $this->assertInternalType( 'array', $plugins, 'Response array is array' );
     162
     163                foreach ( $plugins as $hot_category => $category_array ) {
     164                        $this->assertInternalType( 'array', $category_array, 'Category array is array' );
     165                        $this->assertArrayHasKey( 'name', $category_array, 'Name exists' );
     166                        $this->assertArrayHasKey( 'slug', $category_array, 'Slug exists' );
     167
     168                        // Only check the first result.
     169                        break;
     170                }
     171        }
     172
     173        function test_plugins_api_function_action_hot_tags() {
     174                $number  = 3;
     175                $plugins = plugins_api( 'hot_tags', array( 'number' => $number ) );
     176
     177                $this->assertEquals( $number, count( $plugins ) );
     178                $this->assertInternalType( 'array', $plugins, 'Response array is array' );
     179
     180                foreach ( $plugins as $hot_tag => $tag_array ) {
     181                        $this->assertInternalType( 'array', $tag_array, 'Tag array is array' );
     182                        $this->assertArrayHasKey( 'name', $tag_array, 'Name exists' );
     183                        $this->assertArrayHasKey( 'slug', $tag_array, 'Slug exists' );
     184                        $this->assertArrayHasKey( 'count', $tag_array, 'Count exists' );
     185
     186                        // Only check the first result.
     187                        break;
     188                }
     189        }
     190
     191        function _check_response_plugin_query( $plugin_query, $per_page = 24, $page = 1 ) {
     192                $this->assertObjectHasAttribute( 'info', $plugin_query, 'Info exists' );
     193                $info = $plugin_query->info;
     194
     195                $this->assertArrayHasKey( 'page', $info, 'Page exists' );
     196                $this->assertEquals( $info['page'], $page, 'Page equals to ' . $page );
     197
     198                $this->assertArrayHasKey( 'pages', $info, 'Pages exists' );
     199                $this->assertArrayHasKey( 'results', $info, 'Results exists' );
     200
     201                // Plugins.
     202                $this->assertObjectHasAttribute( 'plugins', $plugin_query, 'Plugins exists' );
     203                $this->assertAttributeInternalType( 'array', 'plugins', $plugin_query, 'Plugins should be an array' );
     204
     205                $this->greaterThanOrEqual( count( $plugin_query->plugins ), $per_page );
     206
     207                $this->_check_response_attributes( $plugin_query->plugins[0] );
     208        }
     209
     210        function _check_response_attributes( $plugin_info ) {
     211                $this->assertObjectHasAttribute( 'name', $plugin_info, 'Name exists' );
     212                $this->assertObjectHasAttribute( 'slug', $plugin_info, 'Slug exits' );
     213                $this->assertObjectHasAttribute( 'version', $plugin_info, 'Version exists' );
     214                $this->assertObjectHasAttribute( 'author', $plugin_info, 'Author exists' );
     215                $this->assertObjectHasAttribute( 'author_profile', $plugin_info, 'Author Profile exists' );
     216                $this->assertObjectHasAttribute( 'contributors', $plugin_info, 'Contributors exists' );
     217                $this->assertAttributeInternalType( 'array', 'contributors', $plugin_info, 'Contributors should be an array' );
     218                $this->assertObjectHasAttribute( 'requires', $plugin_info, 'Requires exists' );
     219                $this->assertObjectHasAttribute( 'tested', $plugin_info, 'Tested exists' );
     220                $this->assertAttributeInternalType( 'string', 'tested', $plugin_info, 'Tested should be a string' );
     221                $this->assertObjectHasAttribute( 'compatibility', $plugin_info, 'Compatibility exists' );
     222                $this->assertAttributeInternalType( 'array', 'compatibility', $plugin_info, 'Compatibility should be an array' );
     223
     224                // Ratings.
     225                $this->assertObjectHasAttribute( 'rating', $plugin_info, 'Rating exists' );
     226                $this->assertObjectHasAttribute( 'ratings', $plugin_info, 'Ratings exists' );
     227                $this->assertAttributeInternalType( 'array', 'ratings', $plugin_info, 'Ratings should be an array' );
     228                $this->assertArrayHasKey( '1', $plugin_info->ratings, 'Rating should have an attribute of 1' );
     229                $this->assertArrayHasKey( '2', $plugin_info->ratings, 'Rating should have an attribute of 2' );
     230                $this->assertArrayHasKey( '3', $plugin_info->ratings, 'Rating should have an attribute of 3' );
     231                $this->assertArrayHasKey( '4', $plugin_info->ratings, 'Rating should have an attribute of 4' );
     232                $this->assertArrayHasKey( '5', $plugin_info->ratings, 'Rating should have an attribute of 5' );
     233                $this->assertObjectHasAttribute( 'num_ratings', $plugin_info, 'Num ratings exists' );
     234                $this->assertTrue( is_numeric( $plugin_info->num_ratings ), 'Num ratings are numeric' );
     235
     236                $this->assertObjectHasAttribute( 'active_installs', $plugin_info, 'Active Installs exists' );
     237                $this->assertAttributeInternalType( 'integer', 'active_installs', $plugin_info, 'Active Installs should be an integer' );
     238                $this->assertObjectHasAttribute( 'downloaded', $plugin_info, 'Active Installs exists' );
     239                $this->assertAttributeInternalType( 'integer', 'downloaded', $plugin_info, 'Downloaded should be an integer' );
     240
     241                $this->assertObjectHasAttribute( 'last_updated', $plugin_info, 'Last Updated exists' );
     242                $this->assertAttributeInternalType( 'string', 'last_updated', $plugin_info, 'Last Updated should be a string' );
     243                $this->assertObjectHasAttribute( 'added', $plugin_info, 'Added exists' );
     244                $this->assertAttributeInternalType( 'string', 'short_description', $plugin_info, 'Added should be a string' );
     245
     246                if ( function_exists( 'date_create_from_format' ) ) {
     247                        $last_updated_date = DateTime::createFromFormat( 'Y-m-d g:ia \G\M\T', $plugin_info->last_updated );
     248                        $date_time_errors  = DateTime::getLastErrors();
     249                        $this->assertTrue( $last_updated_date && 0 == $date_time_errors['warning_count'] && 0 == $date_time_errors['error_count'], 'Last updated has a valid format' );
     250
     251                        $added_date       = DateTime::createFromFormat( 'Y-m-d', $plugin_info->added );
     252                        $date_time_errors = DateTime::getLastErrors();
     253                        $this->assertTrue( $added_date && 0 == $date_time_errors['warning_count'] && 0 == $date_time_errors['error_count'], 'Added has a valid format' );
     254                }
     255
     256                $this->assertObjectHasAttribute( 'homepage', $plugin_info, 'Homepage exists' );
     257                $this->assertAttributeInternalType( 'string', 'homepage', $plugin_info, 'Homepage should be a string' );
     258                $this->assertObjectHasAttribute( 'sections', $plugin_info, 'Sections exists' );
     259                $this->assertAttributeInternalType( 'array', 'sections', $plugin_info, 'Sections should be an array' );
     260
     261                $this->assertObjectHasAttribute( 'description', $plugin_info, 'Description exists' );
     262                $this->assertAttributeInternalType( 'string', 'description', $plugin_info, 'Description should be a string' );
     263                $this->assertObjectHasAttribute( 'short_description', $plugin_info, 'Short Description exists' );
     264                $this->assertAttributeInternalType( 'string', 'short_description', $plugin_info, 'Short Description should be a string' );
     265
     266                $this->assertObjectHasAttribute( 'download_link', $plugin_info, 'Download link exists' );
     267                $this->assertAttributeInternalType( 'string', 'download_link', $plugin_info, 'Download link should be a string' );
     268                $this->assertFalse( empty( $plugin_info->download_link ), 'Download link should have a value' );
     269
     270                $this->assertObjectHasAttribute( 'tags', $plugin_info, 'Tags exists' );
     271                $this->assertAttributeInternalType( 'array', 'tags', $plugin_info, 'Tags should be an array' );
     272
     273                $this->assertObjectHasAttribute( 'stable_tag', $plugin_info, 'Stable tag exists' );
     274                $this->assertAttributeInternalType( 'string', 'stable_tag', $plugin_info, 'Stable tag should be a string' );
     275                $this->assertFalse( empty( $plugin_info->stable_tag ), 'Stable tag should have a value' );
     276
     277                $this->assertObjectHasAttribute( 'versions', $plugin_info, 'Versions exists' );
     278                $this->assertAttributeInternalType( 'array', 'versions', $plugin_info, 'Versions should be an array' );
     279
     280                $this->assertObjectHasAttribute( 'donate_link', $plugin_info, 'Donate link exists' );
     281                $this->assertAttributeInternalType( 'string', 'donate_link', $plugin_info, 'Donate link should be a string' );
     282
     283                $this->assertObjectHasAttribute( 'banners', $plugin_info, 'Banners exists' );
     284                $this->assertAttributeInternalType( 'array', 'banners', $plugin_info, 'Banners should be an array' );
     285
     286                $this->assertObjectHasAttribute( 'icons', $plugin_info, 'Icons exists' );
     287                $this->assertAttributeInternalType( 'array', 'icons', $plugin_info, 'Icons should be an array' );
     288        }
     289}