WordPress.org

Make WordPress Core

Ticket #39264: 39264.5.diff

File 39264.5.diff, 16.4 KB (added by welcher, 9 months ago)

Grunt task added

  • Gruntfile.js

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