Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,11 @@ site.namespace( 'myplugin/v1' ).authors()...

To create a slimmed JSON file dedicated to this particular purpose, see the Node script [lib/data/generate-endpoint-request.js](lib/data/generate-endpoint-request.js), which will let you download and save an endpoint response to your local project.

In addition to retrieving the specified resource with `.get()`, you can also `.create()`, `.update()` and `.delete()` resources:

### Creating Posts

To create posts, use the `.post()` method on a query to POST a data object to the server (POST is the HTTP "verb" equivalent for "create"):
To create posts, use the `.create()` method on a query to POST (the HTTP verb for "create") a data object to the server:

```js
// You must authenticate to be able to POST (create) a post
Expand All @@ -137,7 +139,7 @@ var wp = new WP({
username: 'someusername',
password: 'password'
});
wp.posts().post({
wp.posts().create({
// "title" and "content" are the only required properties
title: 'Your Post Title',
content: 'Your post content',
Expand All @@ -155,7 +157,7 @@ This will work in the same manner for resources other than `post`: you can see t

### Updating Posts

To create posts, use the `.put()` method on a single-item query to PUT a data object to the server (PUT is the HTTP "verb" equivalent for "update"):
To create posts, use the `.update()` method on a single-item query to PUT (the HTTP verb for "update") a data object to the server:

```js
// You must authenticate to be able to PUT (update) a post
Expand All @@ -166,7 +168,7 @@ var wp = new WP({
password: 'password'
});
// .id() must be used to specify the post we are updating
wp.posts().id( 2501 ).post({
wp.posts().id( 2501 ).update({
// Update the title
title: 'A Better Title',
// Set the post live (assuming it was "draft" before)
Expand All @@ -183,13 +185,18 @@ This will work in the same manner for resources other than `post`: you can see t
A WP instance object provides the following basic request methods:

* `wp.posts()...`: Request items from the `/posts` endpoints
* `wp.taxonomies()...`: Generate a request against the `/taxonomies` endpoints
* `wp.pages()...`: Start a request for the `/pages` endpoints
* `wp.users()...`: Get resources within the `/users` endpoints
* `wp.types()...`: Get Post Type collections and objects from the `/types` endpoints
* `wp.comments()...`: Start a request for the `/comments` endpoints
* `wp.taxonomies()...`: Generate a request against the `/taxonomies` endpoints
* `wp.tags()...`: Get or create tags with the `/tags` endpoint
* `wp.categories()...`: Get or create categories with the `/categories` endpoint
* `wp.statuses()...`: Get the available statuses within the `/statuses` endpoint
* `wp.statuses()...`: Get resources within the `/statuses` endpoints
* `wp.users()...`: Get resources within the `/users` endpoints
* `wp.media()...`: Get Media collections and objects from the `/media` endpoints

All of these methods return a customizable request object. The request object can be further refined with chaining methods, and/or sent to the server via `.get()`, `.post()`, `.put()`, `.delete()`, `.head()`, or `.then()`. (Not all endpoints support all methods; for example, you cannot POST or PUT records on `/types`, as these are defined in WordPress plugin or theme code.)
All of these methods return a customizable request object. The request object can be further refined with chaining methods, and/or sent to the server via `.get()`, `.create()`, `.update()`, `.delete()`, `.headers()`, or `.then()`. (Not all endpoints support all methods; for example, you cannot POST or PUT records on `/types`, as these are defined in WordPress plugin or theme code.)

Additional querying methods provided, by endpoint:

Expand Down
108 changes: 93 additions & 15 deletions lib/constructors/wp-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -617,8 +617,8 @@ WPRequest.prototype._renderURI = function() {
// Render the path to a string
var path = this._renderPath();

// If the current request supports filters, render them to a query string
var queryStr = this._renderQuery ? this._renderQuery() : '';
// Render the query string
var queryStr = this._renderQuery();

return this._options.endpoint + path + queryStr;
};
Expand Down Expand Up @@ -722,16 +722,17 @@ WPRequest.prototype.auth = function( usrOrObj, password ) {
return this;
};

// HTTP Methods
// ============
// HTTP Methods: Private HTTP-verb versions
// ========================================

/**
* @method get
* @method _httpGet
* @async
* @private
* @param {Function} [callback] A callback to invoke with the results of the GET request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.get = function( callback ) {
WPRequest.prototype._httpGet = function( callback ) {
this._checkMethodSupport( 'get' );
var url = this._renderURI();

Expand All @@ -741,13 +742,15 @@ WPRequest.prototype.get = function( callback ) {
};

/**
* @method post
* Invoke an HTTP "POST" request against the provided endpoint
* @method _httpPost
* @async
* @private
* @param {Object} data The data for the POST request
* @param {Function} [callback] A callback to invoke with the results of the POST request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.post = function( data, callback ) {
WPRequest.prototype._httpPost = function( data, callback ) {
this._checkMethodSupport( 'post' );
var url = this._renderURI();
data = data || {};
Expand All @@ -758,13 +761,14 @@ WPRequest.prototype.post = function( data, callback ) {
};

/**
* @method put
* @method _httpPut
* @async
* @private
* @param {Object} data The data for the PUT request
* @param {Function} [callback] A callback to invoke with the results of the PUT request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.put = function( data, callback ) {
WPRequest.prototype._httpPut = function( data, callback ) {
this._checkMethodSupport( 'put' );
var url = this._renderURI();
data = data || {};
Expand All @@ -775,13 +779,14 @@ WPRequest.prototype.put = function( data, callback ) {
};

/**
* @method delete
* @method _httpDelete
* @async
* @private
* @param {Object} [data] Data to send along with the DELETE request
* @param {Function} [callback] A callback to invoke with the results of the DELETE request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.delete = function( data, callback ) {
WPRequest.prototype._httpDelete = function( data, callback ) {
if ( ! callback && typeof data === 'function' ) {
callback = data;
data = null;
Expand All @@ -794,19 +799,92 @@ WPRequest.prototype.delete = function( data, callback ) {
};

/**
* @method head
* @method _httpHead
* @async
* @private
* @param {Function} [callback] A callback to invoke with the results of the HEAD request
* @return {Promise} A promise to the header results of the HTTP request
*/
WPRequest.prototype.head = function( callback ) {
WPRequest.prototype._httpHead = function( callback ) {
this._checkMethodSupport( 'head' );
var url = this._renderURI();
var request = this._auth( agent.head( url ) );

return invokeAndPromisify( request, callback, returnHeaders );
};

// HTTP Methods: Public Interface
// ==============================

/** @deprecated Use .create() */
WPRequest.prototype.post = function( data, callback ) {
return this._httpPost( data, callback );
};

/** @deprecated Use .update() */
WPRequest.prototype.put = function( data, callback ) {
return this._httpPut( data, callback );
};

/**
* @method get
* @async
* @param {Function} [callback] A callback to invoke with the results of the GET request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.get = function( callback ) {
return this._httpGet( callback );
};

/**
* Create a HEAD request against a site
* @method headers
* @async
* @param {Function} [callback] A callback to invoke with the results of the HEAD request
* @return {Promise} A promise to the header results of the HTTP request
*/
WPRequest.prototype.headers = function( callback ) {
return this._httpHead( callback );
};

/**
* Invoke an HTTP "POST" request against the provided endpoint
*
* This is the public interface creating for POST requests
*
* @method create
* @async
* @param {Object} data The data for the POST request
* @param {Function} [callback] A callback to invoke with the results of the POST request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.create = function( data, callback ) {
return this._httpPost( data, callback );
};

/**
* @method _httpPut
* @async
* @private
* @param {Object} data The data for the PUT request
* @param {Function} [callback] A callback to invoke with the results of the PUT request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.update = function( data, callback ) {
return this._httpPut( data, callback );
};

/**
* @method delete
* @async
* @param {Object} [data] Data to send along with the DELETE request
* @param {Function} [callback] A callback to invoke with the results of the DELETE request
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.delete = function( data, callback ) {
return this._httpDelete( data, callback );
};

/**
* Calling .then on a query chain will invoke the query as a GET and return a promise
*
Expand All @@ -817,7 +895,7 @@ WPRequest.prototype.head = function( callback ) {
* @return {Promise} A promise to the results of the HTTP request
*/
WPRequest.prototype.then = function( successCallback, failureCallback ) {
return this.get().then( successCallback, failureCallback );
return this._httpGet().then( successCallback, failureCallback );
};

module.exports = WPRequest;
20 changes: 10 additions & 10 deletions tests/integration/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ describe( 'integration: posts()', function() {
return expect( prom ).to.eventually.equal( SUCCESS );
});

it( 'include the total number of posts', function() {
var prom = wp.posts().get().then(function( posts ) {
expect( posts._paging ).to.have.property( 'total' );
expect( posts._paging.total ).to.equal( '38' );
it( 'include the total number of posts: use .headers() for coverage reasons', function() {
var prom = wp.posts().headers().then(function( postHeadersResponse ) {
expect( postHeadersResponse ).to.have.property( 'x-wp-total' );
expect( postHeadersResponse[ 'x-wp-total' ] ).to.equal( '38' );
return SUCCESS;
});
return expect( prom ).to.eventually.equal( SUCCESS );
Expand Down Expand Up @@ -301,8 +301,8 @@ describe( 'integration: posts()', function() {
return expect( prom ).to.eventually.equal( SUCCESS );
});

it( 'cannot POST (create) without authentication', function() {
var prom = wp.posts().post({
it( 'cannot create (POST) without authentication', function() {
var prom = wp.posts().create({
title: 'New Post 2501',
content: 'Some Content'
}).catch(function( err ) {
Expand All @@ -314,11 +314,11 @@ describe( 'integration: posts()', function() {
return expect( prom ).to.eventually.equal( SUCCESS );
});

it( 'cannot PUT (update) without authentication', function() {
it( 'cannot update (PUT) without authentication', function() {
var id;
var prom = wp.posts().perPage( 1 ).get().then(function( posts ) {
id = posts[ 0 ].id;
return wp.posts().id( id ).put({
return wp.posts().id( id ).update({
title: 'New Post 2501',
content: 'Some Content'
});
Expand All @@ -333,7 +333,7 @@ describe( 'integration: posts()', function() {

it( 'can create, update & delete a post when authenticated', function() {
var id;
var prom = wp.posts().auth( credentials ).post({
var prom = wp.posts().auth( credentials ).create({
title: 'New Post 2501',
content: 'Some Content'
}).then(function( createdPost ) {
Expand All @@ -347,7 +347,7 @@ describe( 'integration: posts()', function() {
expect( createdPost ).to.have.property( 'content' );
expect( createdPost.content ).to.have.property( 'raw' );
expect( createdPost.content.raw ).to.equal( 'Some Content' );
return wp.posts().auth( credentials ).id( id ).put({
return wp.posts().auth( credentials ).id( id ).update({
title: 'Updated Title',
status: 'publish'
});
Expand Down
52 changes: 52 additions & 0 deletions tests/unit/lib/constructors/wp-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,19 @@ describe( 'WPRequest', function() {
expect( request._options.auth ).to.be.true;
});

it( 'does not set username/password if they are not provided as string values', function() {
expect( request._options ).not.to.have.property( 'username' );
expect( request._options ).not.to.have.property( 'password' );
request.auth({
username: 123,
password: false
});
expect( request._options ).not.to.have.property( 'username' );
expect( request._options ).not.to.have.property( 'password' );
expect( request._options ).to.have.property( 'auth' );
expect( request._options.auth ).to.be.true;
});

}); // auth

describe( '._auth', function() {
Expand Down Expand Up @@ -834,4 +847,43 @@ describe( 'WPRequest', function() {
}); // Pagination

}); // Request methods

describe( 'deprecated request methods', function() {

describe( '.post()', function() {

it( 'is a function', function() {
expect( request ).to.have.property( 'post' );
expect( request.post ).to.be.a( 'function' );
});

it( 'proxies to ._httpPost', function() {
sinon.stub( request, '_httpPost' );
function cb() {}
request.post( 'foo', cb );
expect( request._httpPost ).to.have.been.calledWith( 'foo', cb );
request._httpPost.restore();
});

});

describe( '.put()', function() {

it( 'is a function', function() {
expect( request ).to.have.property( 'put' );
expect( request.put ).to.be.a( 'function' );
});

it( 'proxies to ._httpPut', function() {
sinon.stub( request, '_httpPut' );
function cb() {}
request.put( 'foo', cb );
expect( request._httpPut ).to.have.been.calledWith( 'foo', cb );
request._httpPut.restore();
});

});

}); // Deprecated request methods

});