Make WordPress Core

Ticket #39264: 39264.4.diff

File 39264.4.diff, 15.7 KB (added by adamsilverstein, 8 years ago)
  • tests/phpunit/tests/rest-api/rest-schema-setup.php

     
     1<?php
     2/**
     3 * Unit tests covering schema initialization.
     4 *
     5 * @package WordPress
     6 * @subpackage REST API
     7 */
     8
     9/**
     10 * @group restapi
     11 * @group restapi-jsclient
     12 */
     13class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
     14
     15        public function setUp() {
     16                parent::setUp();
     17
     18                /** @var WP_REST_Server $wp_rest_server */
     19                global $wp_rest_server;
     20                $this->server = $wp_rest_server = new Spy_REST_Server;
     21                do_action( 'rest_api_init' );
     22        }
     23
     24        public function tearDown() {
     25                parent::tearDown();
     26                remove_filter( 'rest_url', array( $this, 'test_rest_url_for_leading_slash' ), 10, 2 );
     27                /** @var WP_REST_Server $wp_rest_server */
     28                global $wp_rest_server;
     29                $wp_rest_server = null;
     30        }
     31
     32        public function test_expected_routes_in_schema() {
     33                $routes = $this->server->get_routes();
     34
     35                $this->assertTrue( is_array( $routes ), '`get_routes` should return an array.' );
     36                $this->assertTrue( ! empty( $routes ), 'Routes should not be empty.' );
     37
     38                $expected_routes = array(
     39                        '/',
     40                        '/oembed/1.0',
     41                        '/oembed/1.0/embed',
     42                        '/wp/v2',
     43                        '/wp/v2/posts',
     44                        '/wp/v2/posts/(?P<id>[\\d]+)',
     45                        '/wp/v2/posts/(?P<parent>[\\d]+)/revisions',
     46                        '/wp/v2/posts/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)',
     47                        '/wp/v2/pages',
     48                        '/wp/v2/pages/(?P<id>[\\d]+)',
     49                        '/wp/v2/pages/(?P<parent>[\\d]+)/revisions',
     50                        '/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)',
     51                        '/wp/v2/media',
     52                        '/wp/v2/media/(?P<id>[\\d]+)',
     53                        '/wp/v2/types',
     54                        '/wp/v2/types/(?P<type>[\\w-]+)',
     55                        '/wp/v2/statuses',
     56                        '/wp/v2/statuses/(?P<status>[\\w-]+)',
     57                        '/wp/v2/taxonomies',
     58                        '/wp/v2/taxonomies/(?P<taxonomy>[\\w-]+)',
     59                        '/wp/v2/categories',
     60                        '/wp/v2/categories/(?P<id>[\\d]+)',
     61                        '/wp/v2/tags',
     62                        '/wp/v2/tags/(?P<id>[\\d]+)',
     63                        '/wp/v2/users',
     64                        '/wp/v2/users/(?P<id>[\\d]+)',
     65                        '/wp/v2/users/me',
     66                        '/wp/v2/comments',
     67                        '/wp/v2/comments/(?P<id>[\\d]+)',
     68                        '/wp/v2/settings',
     69                );
     70
     71                // Test that each of the expected core routes exists in the schema.
     72                foreach( $expected_routes as $route ) {
     73                        $this->assertTrue( isset( $routes[ $route ] ), $route . ' route should exist in the schema.' );
     74                }
     75}
     76
     77        public function test_routes_in_schema_resolve_correctly() {
     78
     79                // Set up for testing the individual endpoints.
     80                // Set a current admin user.
     81                $administrator = $this->factory->user->create( array(
     82                        'role' => 'administrator',
     83                ) );
     84                wp_set_current_user( $administrator );
     85
     86                // Set up data for endpoints.
     87                $post_id  = $this->factory->post->create();
     88                $page_id  = $this->factory->post->create( array( 'post_type' => 'page' ) );
     89                $tag_id   = $this->factory->tag->create( array( 'name' => 'test' ) );
     90                $media_id = $this->factory->attachment->create_object( '/tmp/canola.jpg', 0, array(
     91                                                'post_mime_type' => 'image/jpeg',
     92                                                'post_excerpt'   => 'A sample caption',
     93                                        ) );
     94                wp_update_post( array( 'post_content' => 'Updated content.', 'ID' => $post_id ) );
     95                wp_update_post( array( 'post_content' => 'Updated content.', 'ID' => $page_id ) );
     96                $comment_id = $this->factory->comment->create( array(
     97                        'comment_approved' => 1,
     98                        'comment_post_ID'  => $post_id,
     99                        'user_id'          => 0,
     100                ) );
     101
     102                // Generate route data for subsequent QUnit tests.
     103                $routes_to_generate_data = array(
     104                        array(
     105                                'route' => '/',
     106                                'name'  => 'Schema',
     107                        ),
     108                        array(
     109                                'route' => '/oembed/1.0',
     110                                'name'  => 'oembed',
     111                        ),
     112                        array(
     113                                'route' => '/oembed/1.0/embed',
     114                                'name'  => 'oembeds',
     115                        ),
     116                        array(
     117                                'route' => '/wp/v2/posts',
     118                                'name'  => 'PostsCollection',
     119                        ),
     120                        array(
     121                                'route' => '/wp/v2/posts/' . $post_id,
     122                                'name'  => 'PostModel',
     123                        ),
     124                        array(
     125                                'route' => '/wp/v2/posts/' . $post_id . '/revisions',
     126                                'name'  => 'postRevisions',
     127                        ),
     128                        array(
     129                                'route' => '/wp/v2/posts/' . $post_id . '/revisions/1',
     130                                'name'  => 'revision',
     131                        ),
     132                        array(
     133                                'route' => '/wp/v2/pages',
     134                                'name'  => 'PagesCollection',
     135                        ),
     136                        array(
     137                                'route' => '/wp/v2/pages/' . $page_id,
     138                                'name'  => 'PageModel',
     139                        ),
     140                        array(
     141                                'route' => '/wp/v2/pages/'. $page_id . '/revisions',
     142                                'name'  => 'pageRevisions',
     143                        ),
     144                        array(
     145                                'route' => '/wp/v2/pages/'. $page_id . '/revisions/1',
     146                                'name'  => 'pageRevision',
     147                        ),
     148                        array(
     149                                'route' => '/wp/v2/media',
     150                                'name'  => 'MediaCollection',
     151                        ),
     152                        array(
     153                                'route' => '/wp/v2/media/' . $media_id,
     154                                'name'  => 'MediaModel',
     155                        ),
     156                        array(
     157                                'route' => '/wp/v2/types',
     158                                'name'  => 'TypesCollection',
     159                        ),
     160                        array(
     161                                'route' => '/wp/v2/types/',
     162                                'name'  => 'TypeModel',
     163                        ),
     164                        array(
     165                                'route' => '/wp/v2/statuses',
     166                                'name'  => 'StatusesCollection',
     167                        ),
     168                        array(
     169                                'route' => '/wp/v2/statuses/publish',
     170                                'name'  => 'StatusModel',
     171                        ),
     172                        array(
     173                                'route' => '/wp/v2/taxonomies',
     174                                'name'  => 'TaxonomiesCollection',
     175                        ),
     176                        array(
     177                                'route' => '/wp/v2/taxonomies/category',
     178                                'name'  => 'TaxonomyModel',
     179                        ),
     180                        array(
     181                                'route' => '/wp/v2/categories',
     182                                'name'  => 'CategoriesCollection',
     183                        ),
     184                        array(
     185                                'route' => '/wp/v2/categories/1',
     186                                'name'  => 'CategoryModel',
     187                        ),
     188                        array(
     189                                'route' => '/wp/v2/tags',
     190                                'name'  => 'TagsCollection',
     191                        ),
     192                        array(
     193                                'route' => '/wp/v2/tags/' . $tag_id,
     194                                'name'  => 'TagModel',
     195                        ),
     196                        array(
     197                                'route' => '/wp/v2/users',
     198                                'name'  => 'UsersCollection',
     199                        ),
     200                        array(
     201                                'route' => '/wp/v2/users/1',
     202                                'name'  => 'UserModel',
     203                        ),
     204                        array(
     205                                'route' => '/wp/v2/users/me',
     206                                'name'  => 'me',
     207                        ),
     208                        array(
     209                                'route' => '/wp/v2/comments',
     210                                'name'  => 'CommentsCollection',
     211                        ),
     212                        array(
     213                                'route' => '/wp/v2/comments/1',
     214                                'name'  => 'CommentModel',
     215                        ),
     216                        array(
     217                                'route' => '/wp/v2/settings',
     218                                'name'  => 'settings',
     219                        ),
     220                );
     221
     222                $mocked_responses = "var mockedApiResponse = {};\n\n";
     223
     224                foreach( $routes_to_generate_data as $route ) {
     225                        $request = new WP_REST_Request( 'GET', $route['route'] );
     226                        $response = $this->server->dispatch( $request );
     227                        $data = $response->get_data();
     228
     229                        $this->assertTrue( ! empty( $data ), $route['name'] . ' route should return data.' );
     230
     231                        $mocked_responses .= 'mockedApiResponse.' . $route['name'] . ' = ' . json_encode( $data ) . ";\n\n";
     232                }
     233
     234                // Save the route object for QUnit tests.
     235                $file = './tests/qunit/fixtures/wp-api.js';
     236                file_put_contents( $file, $mocked_responses );
     237
     238                // Clean up our test data.
     239                wp_delete_post( $post_id, true );
     240                wp_delete_post( $page_id, true );
     241                wp_delete_term( $tag_id, 'tags' );
     242                wp_delete_attachment( $media_id );
     243                wp_delete_comment( $comment_id );
     244
     245        }
     246
     247
     248}
  • tests/qunit/fixtures/wp-api-2.js

     
     1
     2var pathToData = {
     3'wp-json/wp/v2/': mockedApiResponse.Schema,
     4'wp-json/wp/v2/categories': mockedApiResponse.CategoriesCollection,
     5'wp-json/wp/v2/comments': mockedApiResponse.CommentsCollection,
     6'wp-json/wp/v2/media': mockedApiResponse.MediaCollection,
     7'wp-json/wp/v2/pages': mockedApiResponse.PagesCollection,
     8'wp-json/wp/v2/posts': mockedApiResponse.PostsCollection,
     9'wp-json/wp/v2/statuses': mockedApiResponse.StatusesCollection,
     10'wp-json/wp/v2/tags': mockedApiResponse.TagsCollection,
     11'wp-json/wp/v2/taxonomies': mockedApiResponse.TaxonomiesCollection,
     12'wp-json/wp/v2/types': mockedApiResponse.TypesCollection,
     13'wp-json/wp/v2/users': mockedApiResponse.UsersCollection,
     14'wp-json/wp/v2/category': mockedApiResponse.CategoryModel,
     15'wp-json/wp/v2/media1': mockedApiResponse.MediaModel,
     16'wp-json/wp/v2/page': mockedApiResponse.PageModel,
     17'wp-json/wp/v2/post': mockedApiResponse.PostModel,
     18'wp-json/wp/v2/tag': mockedApiResponse.TagModel,
     19'wp-json/wp/v2/user': mockedApiResponse.UserModel,
     20'wp-json/wp/v2/taxonomy': mockedApiResponse.TaxonomyModel,
     21'wp-json/wp/v2/status': mockedApiResponse.StatusModel,
     22'wp-json/wp/v2/type': mockedApiResponse.TypeModel
     23};
     24
     25/**
     26 * Mock the ajax callbacks for our tests.
     27 *
     28 * @param  {object} param The parameters sent to the ajax request.
     29 *
     30 * @return {Object}       A jQuery defered object that resolves with the mapped data.
     31 */
     32Backbone.ajax = function ( param ) {
     33
     34        var data,
     35                request = param.url.replace( 'http://localhost/', '' );
     36
     37        if ( pathToData[ request ] ) {
     38                data = pathToData[ request ];
     39        }
     40
     41        // Call success handler.
     42        param.success( data );
     43        var deferred = jQuery.Deferred();
     44
     45        // Resolve the deferred with the mocked data
     46        deferred.resolve( data );
     47
     48        // Return the deferred promise that will resolve with the expected data.
     49        return deferred.promise();
     50
     51};
  • tests/qunit/index.html

     
    1717                                }
    1818                        };
    1919                </script>
     20                <script>
     21                        var wpApiSettings = {
     22                                'root': 'http://localhost/wp-json/'
     23                        };
     24                </script>
    2025                <script src="../../src/wp-includes/js/wp-util.js"></script>
    2126                <script src="../../src/wp-includes/js/wp-a11y.js"></script>
    2227
     
    3439                        <script src="fixtures/customize-settings.js"></script>
    3540                        <script src="fixtures/customize-menus.js"></script>
    3641                        <script src="fixtures/customize-widgets.js"></script>
     42                        <script src="fixtures/wp-api.js"></script>
     43                        <script src="fixtures/wp-api-2.js"></script>
    3744                </div>
    3845                <p><a href="editor">TinyMCE tests</a></p>
    3946
     
    4350                <script src="../../src/wp-includes/js/customize-models.js"></script>
    4451                <script src="../../src/wp-includes/js/shortcode.js"></script>
    4552                <script src="../../src/wp-admin/js/customize-controls.js"></script>
     53                <script src="../../src/wp-includes/js/wp-api.js"></script>
    4654
    4755                <script type='text/javascript' src='../../src/wp-includes/js/jquery/ui/core.js'></script>
    4856                <script type='text/javascript' src='../../src/wp-includes/js/jquery/ui/widget.js'></script>
     
    6169                <script src="wp-admin/js/customize-base.js"></script>
    6270                <script src="wp-admin/js/customize-header.js"></script>
    6371                <script src="wp-includes/js/shortcode.js"></script>
     72                <script src="wp-includes/js/wp-api.js"></script>
    6473                <script src="wp-admin/js/customize-controls.js"></script>
    6574                <script src="wp-admin/js/customize-controls-utils.js"></script>
    6675                <script src="wp-admin/js/customize-nav-menus.js"></script>
  • tests/qunit/wp-includes/js/wp-api.js

     
     1/* global wp */
     2( function( QUnit ) {
     3        module( 'wpapi' );
     4
     5        QUnit.test( 'API Loaded correctly', function( assert ) {
     6                var done = assert.async();
     7                assert.expect( 2 );
     8
     9                assert.ok( wp.api.loadPromise );
     10
     11                //wp.api.init();
     12                wp.api.loadPromise.done( function() {
     13                        assert.ok( wp.api.models );
     14                        done();
     15                } );
     16
     17        } );
     18
     19
     20        // The list of collections we should check.
     21        var collectionClassNames = [
     22                        'Categories',
     23                        'Comments',
     24                        'Media',
     25                        'Pages',
     26                        'Posts',
     27                        'Statuses',
     28                        'Tags',
     29                        'Taxonomies',
     30                        'Types',
     31                        'Users'
     32                ];
     33
     34        // Collections that should get helpers tested.
     35        var collectionHelperTests = [
     36                {
     37                        'collectionType':   'Posts',
     38                        'returnsModelType': 'post',
     39                        'supportsMethods':  {
     40                                'getDate':          'getDate',
     41                                'getRevisions':     'getRevisions',
     42                                'getTags':          'getTags',
     43                                'getCategories':    'getCategories',
     44                                'getAuthorUser':    'getAuthorUser',
     45                                'getFeaturedMedia': 'getFeaturedMedia'
     46                                /*'getMeta':        'getMeta', currently not supported */
     47                        }
     48                },
     49                {
     50                        'collectionType':   'Pages',
     51                        'returnsModelType': 'page',
     52                        'supportsMethods':  {
     53                                'getDate':          'getDate',
     54                                'getRevisions':     'getRevisions',
     55                                'getAuthorUser':    'getAuthorUser',
     56                                'getFeaturedMedia': 'getFeaturedMedia'
     57                        }
     58                }
     59        ];
     60
     61        _.each( collectionClassNames, function( className ) {
     62                QUnit.test( 'Testing ' + className + ' collection.', function( assert ) {
     63                        var done = assert.async();
     64
     65                        wp.api.loadPromise.done( function() {
     66                                var theCollection = new wp.api.collections[ className ]();
     67                                assert.ok(
     68                                        theCollection,
     69                                        'We can instantiate wp.api.collections.' + className
     70                                );
     71                                theCollection.fetch().done( function( response ) {
     72                                        assert.equal(
     73                                                1,
     74                                                theCollection.state.currentPage,
     75                                                'We should be on page 1 of the collection in ' + className
     76                                        );
     77
     78                                                // Should this collection have helper methods?
     79                                                var collectionHelperTest = _.findWhere( collectionHelperTests, { 'collectionType': className } );
     80
     81                                                // If we found a match, run the tests against it.
     82                                                if ( ! _.isUndefined( collectionHelperTest ) ) {
     83
     84                                                        // Test the first returned model.
     85                                                        var firstModel = theCollection.at( 0 );
     86
     87                                                        // Is the model the right type?
     88                                                        assert.equal(
     89                                                                collectionHelperTest.returnsModelType,
     90                                                                firstModel.get( 'type' ),
     91                                                                'The wp.api.collections.' + className + ' is of type ' + collectionHelperTest.returnsModelType
     92                                                        );
     93
     94                                                        // Does the model have all of the expected supported methods?
     95                                                        _.each( collectionHelperTest.supportsMethods, function( method ) {
     96                                                                assert.equal(
     97                                                                        'function',
     98                                                                        typeof firstModel[ method ],
     99                                                                        className + '.' + method + ' is a function.'
     100                                                                );
     101                                                        } );
     102                                                }
     103
     104                                        // Trigger Qunit async completion.
     105                                        done();
     106                                } );
     107
     108                        } );
     109
     110                });
     111        } );
     112
     113        // The list of models we should check.
     114        var modelsWithIdsClassNames =
     115                [
     116                        'Category',
     117                        'Media',
     118                        'Page',
     119                        'Post',
     120                        'Tag',
     121                        'User'
     122                ];
     123
     124
     125        _.each( modelsWithIdsClassNames, function( className ) {
     126
     127                QUnit.test( 'Checking ' + className + ' model.' , function( assert ) {
     128                        var done = assert.async();
     129
     130                        assert.expect( 2 );
     131
     132                        wp.api.loadPromise.done( function() {
     133                                var theModel = new wp.api.models[ className ]();
     134                                assert.ok( theModel, 'We can instantiate wp.api.models.' + className );
     135                                theModel.fetch().done( function(  ) {
     136                                        var theModel2 = new wp.api.models[ className ]();
     137                                        theModel2.set( 'id', theModel.attributes[0].id );
     138                                        theModel2.fetch().done( function( response ) {
     139
     140                                                // We were able to retrieve the model.
     141                                                assert.equal(
     142                                                        theModel.attributes[0].id,
     143                                                        theModel2.get( 'id' ) ,
     144                                                        'We should be able to get a ' + className
     145                                                );
     146
     147                                                // Trigger Qunit async completion.
     148                                                done();
     149                                        } );
     150                                } );
     151
     152                        } );
     153
     154                });
     155        } );
     156
     157        var modelsWithIndexes =
     158                [
     159                        'Taxonomy',
     160                        'Status',
     161                        'Type'
     162                ];
     163
     164        _.each( modelsWithIndexes, function( className ) {
     165
     166                QUnit.test( 'Testing ' + className + ' model.' , function( assert ) {
     167                        var done = assert.async();
     168
     169                        assert.expect( 2 );
     170
     171                        wp.api.loadPromise.done( function(  ) {
     172
     173                                var theModel = new wp.api.models[ className ]();
     174                                assert.ok( theModel, 'We can instantiate wp.api.models.' + className );
     175                                theModel.fetch().done( function(  ) {
     176                                        var theModel2 = new wp.api.models[ className ]();
     177
     178                                        if ( ! _.isUndefined( theModel.attributes[0] ) ) {
     179                                                theModel2.set( 'id', theModel.attributes[0].id );
     180                                        }
     181
     182                                        theModel2.fetch().done( function( response ) {
     183
     184                                                // We were able to retrieve the model.
     185                                                assert.notEqual(
     186                                                        0,
     187                                                        _.keys( theModel2.attributes ).length ,
     188                                                        'We should be able to get a ' + className
     189                                                );
     190
     191                                                // Trigger Qunit async completion.
     192                                                done();
     193                                        } );
     194                                } );
     195
     196                        } );
     197
     198                });
     199        } );
     200
     201
     202} )( window.QUnit );