• Skip to primary navigation
  • Skip to main content
  • Skip to footer

JH Tech Services

A knowledgebase

  • Portfolio
  • Knowledgebase
  • About

wp_verify_nonce and PHPUnit testing

February 17, 2017 by jer0dh

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

  • Knowledgebase
  • PHP
  • Wordpress

Footer

  • Portfolio
  • Knowledgebase
  • About

© 2023