When testing a plugin function that is using wp_verify_nonce
, we will want that wp_verify_nonce
to not return false in our testing environment. (We are using PHPUnit and WP-CLI – see links below on helpful articles to set this environment up)
We were testing a plugin function that is hooked into the ‘save_post’ action. It will save some custom fields we added to the edit screen.
The first part of this plugin function is this if
statement that will just return and not save the custom fields if the wp_verify_nonce
fails.
public function save_post( $post_id, $post ) {
if ( 'revision' == $post->post_type ) {
return;
}
if ( ! wp_verify_nonce( $_POST['loc-8-nonce'], 'loc-8-' ) || ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
...rest of code
To have wp_verify_nonce
verify the nonce in this environment we need to do the following:
- Create a user
- Set that user as the current user
- Create a nonce with the same action string(in this case, it’s ‘loc-8-‘)
- Put this nonce in the global `$_POST` array
It’s important also that you do this in that order. You must set the current user before you create the nonce.
This is our test function that will do all this for us. It will allow us to run the save_post
function and run the rest of the code after the wp_verify_nonce
if statement
function test_save_post() {
// create a user
$author1 = $this->factory->user->create_and_get( array( 'user_login' => 'jdoe', 'user_pass' => NULL, 'role' => 'author' ));
// Make sure it was created in this testing environment
$this->assertTrue( 0 !== $author1->ID );
// Create a test post and set the author as $author1
$post1 = $this->factory->post->create_and_get( array( 'post_title' => 'Test Post', 'post_author' => $author1->ID ));
// Make sure it was created in this testing environment
$this->assertTrue( 0 !== $post1->ID );
// Set the current user to $author1
wp_set_current_user( $author1->ID );
// create a nonce with the same action our production code uses
$loc_8_nonce = wp_create_nonce('loc-8-');
// set $_POST array with nonce
$_POST['loc-8-nonce'] = $loc_8_nonce;
// Here we would add some test custom field data that would be in the $_POST array
$_POST['loc-8-lat'] = '1.2222';
$_POST['loc-8-long'] = '-12.3344';
//Now we can run our save_post function (our setUp function loads our plugin class and sets it to a private variable called `$plugin`
$this->plugin->save_post($post1->ID, $post1);
//Here we test to see if the custom fields are added
$this->assertTrue( '1.2222' === get_post_meta( $post1->ID, 'loc_8_lat', true) );
$this->assertTrue( '-12.3344' === get_post_meta( $post1->ID, 'loc_8_long', true) );
}
You could also test if wp_verify_nonce
will work before you call save_post
using an assertTrue, but remember that it returns 1 or 2 if the nonce is verified and false if it does not verify.
A helpful link on unit testing wordpress:
Unit Tests for WordPress Plugins