Ticket #39264: 39264.5.diff
File 39264.5.diff, 16.4 KB (added by , 8 years ago) |
---|
-
Gruntfile.js
439 439 'external-http': { 440 440 cmd: 'phpunit', 441 441 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'] 442 446 } 447 443 448 }, 444 449 uglify: { 445 450 options: { … … 672 677 'jshint:media' 673 678 ] ); 674 679 680 681 grunt.registerTask( 'rest-api-jsclient',[ 682 'phpunit:wp-api-jsclient', 683 'qunit' 684 ]); 685 675 686 grunt.renameTask( 'watch', '_watch' ); 676 687 677 688 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 */ 13 class 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 2 var 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 */ 32 Backbone.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
17 17 } 18 18 }; 19 19 </script> 20 <script> 21 var wpApiSettings = { 22 'root': 'http://localhost/wp-json/' 23 }; 24 </script> 20 25 <script src="../../src/wp-includes/js/wp-util.js"></script> 21 26 <script src="../../src/wp-includes/js/wp-a11y.js"></script> 22 27 … … 34 39 <script src="fixtures/customize-settings.js"></script> 35 40 <script src="fixtures/customize-menus.js"></script> 36 41 <script src="fixtures/customize-widgets.js"></script> 42 <script src="fixtures/wp-api.js"></script> 43 <script src="fixtures/wp-api-2.js"></script> 37 44 </div> 38 45 <p><a href="editor">TinyMCE tests</a></p> 39 46 … … 43 50 <script src="../../src/wp-includes/js/customize-models.js"></script> 44 51 <script src="../../src/wp-includes/js/shortcode.js"></script> 45 52 <script src="../../src/wp-admin/js/customize-controls.js"></script> 53 <script src="../../src/wp-includes/js/wp-api.js"></script> 46 54 47 55 <script type='text/javascript' src='../../src/wp-includes/js/jquery/ui/core.js'></script> 48 56 <script type='text/javascript' src='../../src/wp-includes/js/jquery/ui/widget.js'></script> … … 61 69 <script src="wp-admin/js/customize-base.js"></script> 62 70 <script src="wp-admin/js/customize-header.js"></script> 63 71 <script src="wp-includes/js/shortcode.js"></script> 72 <script src="wp-includes/js/wp-api.js"></script> 64 73 <script src="wp-admin/js/customize-controls.js"></script> 65 74 <script src="wp-admin/js/customize-controls-utils.js"></script> 66 75 <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 );