From 10ef671e301ae69683206113bf6a97e2855b338e Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Mon, 8 Sep 2014 17:30:38 -0400 Subject: [PATCH 01/29] initial commit of unit tests --- .gitignore | 1 + .travis.yml | 16 ++ bin/install-wp-tests.sh | 78 ++++++++ multi-post-thumbnails.php | 179 ++++++++++++++++--- phpunit.xml | 14 ++ tests/bootstrap.php | 17 ++ tests/test-multi-post-thumbnails.php | 257 +++++++++++++++++++++++++++ 7 files changed, 542 insertions(+), 20 deletions(-) create mode 100644 .travis.yml create mode 100644 bin/install-wp-tests.sh create mode 100644 phpunit.xml create mode 100644 tests/bootstrap.php create mode 100644 tests/test-multi-post-thumbnails.php diff --git a/.gitignore b/.gitignore index 241dfb8..75cc22b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ svn .DS_Store node_modules +coverage diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..64be0af --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: php + +php: + - 5.3 + - 5.4 + +env: + - WP_VERSION=latest WP_MULTISITE=0 + - WP_VERSION=latest WP_MULTISITE=1 + - WP_VERSION=3.8 WP_MULTISITE=0 + - WP_VERSION=3.8 WP_MULTISITE=1 + +before_script: + - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION + +script: phpunit diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh new file mode 100644 index 0000000..1e39064 --- /dev/null +++ b/bin/install-wp-tests.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +if [ $# -lt 3 ]; then + echo "usage: $0 [db-host] [wp-version]" + exit 1 +fi + +DB_NAME=$1 +DB_USER=$2 +DB_PASS=$3 +DB_HOST=${4-localhost} +WP_VERSION=${5-latest} + +WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} +WP_CORE_DIR=/tmp/wordpress/ + +set -ex + +install_wp() { + mkdir -p $WP_CORE_DIR + + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + + wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz + tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + + wget -nv -O $WP_CORE_DIR/wp-content/db.php https://raw.github.com/markoheijnen/wp-mysqli/master/db.php +} + +install_test_suite() { + # portable in-place argument for both GNU sed and Mac OSX sed + if [[ $(uname -s) == 'Darwin' ]]; then + local ioption='-i .bak' + else + local ioption='-i' + fi + + # set up testing suite + mkdir -p $WP_TESTS_DIR + cd $WP_TESTS_DIR + svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ + + wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php +} + +install_db() { + # parse DB_HOST for port or socket references + local PARTS=(${DB_HOST//\:/ }) + local DB_HOSTNAME=${PARTS[0]}; + local DB_SOCK_OR_PORT=${PARTS[1]}; + local EXTRA="" + + if ! [ -z $DB_HOSTNAME ] ; then + if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi + fi + + # create database + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} + +install_wp +install_test_suite +install_db diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 98e84cc..5e89682 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -29,6 +29,13 @@ class MultiPostThumbnails { + protected $args; + public $label; + public $id; + protected $post_type; + protected $priority; + protected $context; + public function __construct($args = array()) { $this->register($args); } @@ -54,8 +61,9 @@ public function __construct($args = array()) { * @return void */ public function register($args = array()) { + global $wp_version; - + $defaults = array( 'label' => null, 'id' => null, @@ -64,28 +72,31 @@ public function register($args = array()) { 'context' => 'side', ); - $args = wp_parse_args($args, $defaults); + $this->args = wp_parse_args($args, $defaults); // Create and set properties - foreach($args as $k => $v) { + + foreach( $this->args as $k => $v ) { $this->$k = $v; } + + // Need these args to be set at a minimum if (null === $this->label || null === $this->id) { - if (WP_DEBUG) { - trigger_error(sprintf(__("The 'label' and 'id' values of the 'args' parameter of '%s::%s()' are required", 'multiple-post-thumbnails'), __CLASS__, __FUNCTION__)); + if ( WP_DEBUG ) { + $this->trigger_error(sprintf(__("The 'label' and 'id' values of the 'args' parameter of '%s::%s()' are required", 'multiple-post-thumbnails'), __CLASS__, __FUNCTION__)); } return; } // add theme support if not already added - if (!current_theme_supports('post-thumbnails')) { - add_theme_support( 'post-thumbnails' ); + if ( ! $this->current_theme_supports('post-thumbnails')) { + $this->add_theme_support( 'post-thumbnails' ); } add_action('add_meta_boxes', array($this, 'add_metabox')); - if (version_compare($wp_version, '3.5', '<')) { + if ( $this->version_compare($wp_version, '3.5', '<')) { add_filter('attachment_fields_to_edit', array($this, 'add_attachment_field'), 20, 2); } add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts')); @@ -94,8 +105,9 @@ public function register($args = array()) { add_action("wp_ajax_set-{$this->post_type}-{$this->id}-thumbnail", array($this, 'set_thumbnail')); add_action('delete_attachment', array($this, 'action_delete_attachment')); add_filter('is_protected_meta', array($this, 'filter_is_protected_meta'), 20, 2); + } - + /** * get the meta key used to store a post's thumbnail * @@ -121,9 +133,10 @@ public function add_metabox() { */ public function thumbnail_meta_box() { global $post; - - $thumbnail_id = get_post_meta($post->ID, $this->get_meta_key(), true); - echo $this->post_thumbnail_html($thumbnail_id); + + $thumbnail_id = $this->get_post_meta($post->ID, $this->get_meta_key(), true); + echo $this->post_thumbnail_html($thumbnail_id); + } /** @@ -134,6 +147,7 @@ public function thumbnail_meta_box() { * @return void */ public function add_attachment_field($form_fields, $post) { + $calling_post_id = 0; if (isset($_GET['post_id'])) $calling_post_id = absint($_GET['post_id']); @@ -144,18 +158,19 @@ public function add_attachment_field($form_fields, $post) { return $form_fields; // check the post type to see if link needs to be added - $calling_post = get_post($calling_post_id); + $calling_post = $this->get_post($calling_post_id); + if (is_null($calling_post) || $calling_post->post_type != $this->post_type) { return $form_fields; } $referer = wp_get_referer(); - $query_vars = wp_parse_args(parse_url($referer, PHP_URL_QUERY)); - + $query_vars = $this->wp_parse_args(parse_url($referer, PHP_URL_QUERY)); + if( (isset($_REQUEST['context']) && $_REQUEST['context'] != $this->id) || (isset($query_vars['context']) && $query_vars['context'] != $this->id) ) return $form_fields; - $ajax_nonce = wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$calling_post_id}"); + $ajax_nonce = $this->wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$calling_post_id}"); $link = sprintf('' . __( 'Set as %3$s', 'multiple-post-thumbnails' ) . '', $this->id, $post->ID, $this->label, $this->post_type, $ajax_nonce); $form_fields["{$this->post_type}-{$this->id}-thumbnail"] = array( 'label' => $this->label, @@ -167,6 +182,8 @@ public function add_attachment_field($form_fields, $post) { /** * Enqueue admin JavaScripts * + * @param $hook + * * @return void */ public function enqueue_admin_scripts( $hook ) { @@ -176,7 +193,7 @@ public function enqueue_admin_scripts( $hook ) { if ( ! in_array( $hook, array( 'post-new.php', 'post.php', 'media-upload-popup' ) ) ) return; - if (version_compare($wp_version, '3.5', '<')) { + if ($this->version_compare($wp_version, '3.5', '<')) { add_thickbox(); wp_enqueue_script( "mpt-featured-image", $this->plugins_url( 'js/multi-post-thumbnails-admin.js', __FILE__ ), array( 'jquery', 'media-upload' ) ); } else { // 3.5+ media modal @@ -362,13 +379,13 @@ public static function get_post_thumbnail_url($post_type, $id, $post_id = 0, $si * @param string $thumbnail_id The thumbnail's post ID. * @return string HTML */ - private function post_thumbnail_html($thumbnail_id = null) { + protected function post_thumbnail_html($thumbnail_id = null) { global $content_width, $_wp_additional_image_sizes, $post_ID, $wp_version; $url_class = ""; $ajax_nonce = wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); - if (version_compare($wp_version, '3.5', '<')) { + if ($this->version_compare($wp_version, '3.5', '<')) { // Use the old thickbox for versions prior to 3.5 $image_library_url = get_upload_iframe_src('image'); // if TB_iframe is not moved to end of query string, thickbox will remove all query args after it. @@ -406,7 +423,7 @@ private function post_thumbnail_html($thumbnail_id = null) { $content_width = $old_content_width; } - if (version_compare($wp_version, '3.5', '>=')) { + if ($this->version_compare($wp_version, '3.5', '>=')) { $content .= sprintf('', $modal_js); } @@ -456,6 +473,128 @@ public static function set_meta($post_ID, $post_type, $thumbnail_id, $thumbnail_ return update_post_meta($post_ID, "{$post_type}_{$thumbnail_id}_thumbnail_id", $thumbnail_post_id); } + + /** + * Helper method to assist testing of a global function + * @param $error_msg + * @param int $error_type + * + * @return bool + * + * @codeCoverageIgnore + */ + function trigger_error( $error_msg, $error_type = E_USER_NOTICE ){ + + if ( ! defined('WP_TEST_ENVIRONMENT') || WP_TEST_ENVIRONMENT === false ){ + + return trigger_error( $error_msg, $error_type ); + + } + + } + + /** + * Helper method to assist mocking/testing of a global function + * @param $feature + * + * @return bool + * + * @codeCoverageIgnore + */ + function add_theme_support( $feature ) { + + return add_theme_support( $feature ); + + } + + /** + * Helper method to assist mocking/testing of a global function + * @param $feature + * + * @return bool + * + * @codeCoverageIgnore + */ + function current_theme_supports( $feature ) { + + return current_theme_supports( $feature ); + + } + + /** + * Helper method to assist mocking/testing of a global function + * @param $version1 + * @param $version2 + * @param null $operator + * + * @return mixed + * + * @codeCoverageIgnorep + */ + public function version_compare ( $version1, $version2, $operator = null ) { + + return version_compare( $version1, $version2, $operator ); + + } + + + /** + * Helper method to assist mocking/testing of a global function + * @param $post_id + * @param string $key + * @param bool $single + * + * @return mixed + * + * @codeCoverageIgnore + */ + public function get_post_meta( $post_id, $key = '', $single = false ) { + + return get_post_meta( $post_id, $key, $single ); + + } + + + /** + * Helper method to assist mocking/testing of a global function + * + * @param $args + * @param string $defaults + * + * @return array + * + * @codeCoverageIgnore + */ + public function wp_parse_args( $args, $defaults = '' ){ + + return wp_parse_args( $args, $defaults ); + + } + + public function wp_create_nonce( $action ){ + + return wp_create_nonce( $action ); + + } + + /** + * Helper method to assist mocking/testing of a global function + * + * @param null $post + * @param string $output + * @param string $filter + * + * @return null|WP_Post + * + * @codeCoverageIgnore + */ + public function get_post( $post = null, $output = OBJECT, $filter = 'raw' ){ + + return get_post( $post, $output, $filter ); + + } + + } if ( is_admin() ) diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..44f0fdb --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,14 @@ + + + + ./tests/ + + + diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..6a800da --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,17 @@ +getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'version_compare', 'current_theme_supports', 'trigger_error', 'add_theme_support' ) ) + ->getMock(); + + $mpt->expects( $this->exactly( $current_theme_supports_expects ) ) + ->method( 'current_theme_supports' ) + ->will( $this->returnValue( $current_theme_supports ) ); + + $mpt->expects( $this->exactly( $add_theme_support_expects ) ) + ->method( 'add_theme_support' ) + ->will( $this->returnValue( $add_theme_support ) ); + + $mpt->expects( $this->exactly( $version_compare_expects ) ) + ->method( 'version_compare' ) + ->will( $this->returnValue( $version_compare ) ); + + if ( ! $id || ! $label ) { + + $mpt->expects( $this->once() ) + ->method( 'trigger_error' ); + + } + + + $mpt->register( array( 'label' => $label, 'id' => $id ) ); + + if ( $assertFilters ) { + + + $this->assertEquals( has_action( 'add_meta_boxes', array( $mpt, 'add_metabox' ) ), 10 ); + if ( $version_compare ) { + $this->assertEquals( has_filter( 'attachment_fields_to_edit', array( $mpt, 'add_attachment_field' ) ), 20 ); + } + $this->assertEquals( has_filter( 'admin_enqueue_scripts', array( $mpt, 'enqueue_admin_scripts' ) ), 10 ); + $this->assertEquals( has_filter( 'admin_print_scripts-post.php', array( $mpt, 'admin_header_scripts' ) ), 10 ); + $this->assertEquals( has_filter( 'admin_print_scripts-post-new.php', array( $mpt, 'admin_header_scripts' ) ), 10 ); + $this->assertEquals( has_filter( 'wp_ajax_set-' . $post_type . '-' . $id . '-thumbnail', array( $mpt, 'set_thumbnail' ) ), 10 ); + $this->assertEquals( has_filter( 'delete_attachment', array( $mpt, 'action_delete_attachment' ) ), 10 ); + $this->assertEquals( has_filter( 'is_protected_meta', array( $mpt, 'filter_is_protected_meta' ) ), 20 ); + + + } + + + } + + function test_get_meta_key() { + + $mpt = new MultiPostThumbnails( array( 'label' => 'foo', 'id' => 'bar', 'post_type' => 'post' ) ); + + $actual = $mpt->get_meta_key(); + + $expected = 'post_bar_thumbnail_id'; + + $this->assertEquals( $expected, $actual ); + + } + + + function test_add_metabox() { + + global $wp_meta_boxes; + + $mpt = new MultiPostThumbnails( array( 'label' => 'foo', 'id' => 'bar', 'post_type' => 'post', 'context' => 'default', 'priority' => 'high' ) ); + + $mpt->add_metabox(); + + $this->assertArrayHasKey( 'post-bar', $wp_meta_boxes['post']['default']['high'] ); + + } + + function test_thumbnail_meta_box() { + + $post_id = 123; + $GLOBALS['post'] = (object) array( 'ID' => $post_id ); + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'post_thumbnail_html', 'get_post_meta', 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'get_meta_key' ) + ->will( $this->returnValue( 'metaKey' ) ); + + + $mpt->expects( $this->once() ) + ->method( 'get_post_meta' ) + ->with( $this->equalTo( $post_id ), $this->equalTo( 'metaKey' ), true ) + ->will( $this->returnValue( 'thumbnailid' ) ); + + $mpt->expects( $this->once() ) + ->method( 'post_thumbnail_html' ); + + $mpt->thumbnail_meta_box(); + + + } + + function test_add_attachment_field_none() { + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'wp_parse_args', 'wp_create_nonce', 'get_post' ) ) + ->getMock(); + + $mpt->expects( $this->never() ) + ->method( 'wp_parse_args' ); + + $mpt->expects( $this->never() ) + ->method( 'wp_create_nonce' ); + + $mpt->expects( $this->never() ) + ->method( 'get_post' ); + + $actual = $mpt->add_attachment_field( 'foo', 'bar' ); + $expected = 'foo'; + + $this->assertEquals( $expected, $actual ); + + + } + + function test_add_attachment_field_get_calling_post_id_null() { + + $_GET['post_id'] = 123; + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'wp_parse_args', 'wp_create_nonce', 'get_post' ) ) + ->getMock(); + + $mpt->expects( $this->never() ) + ->method( 'wp_parse_args' ); + + $mpt->expects( $this->never() ) + ->method( 'wp_create_nonce' ); + + $mpt->expects( $this->once() ) + ->method( 'get_post' ) + ->will( $this->returnValue( null ) ); + + $actual = $mpt->add_attachment_field( 'foo', 'bar' ); + $expected = 'foo'; + + $this->assertEquals( $expected, $actual ); + + } + + function test_add_attachment_field_get_unsupported_post_type() { + + $_GET['post_id'] = 123; + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'wp_parse_args', 'wp_create_nonce', 'get_post' ) ) + ->getMock(); + + $mpt->expects( $this->never() ) + ->method( 'wp_parse_args' ); + + $mpt->expects( $this->never() ) + ->method( 'wp_create_nonce' ); + + $mpt->expects( $this->once() ) + ->method( 'get_post' ) + ->will( $this->returnValue( (object) array( 'post_type' => 'not a known post type' ) ) ); + + $actual = $mpt->add_attachment_field( 'foo', 'bar' ); + $expected = 'foo'; + + $this->assertEquals( $expected, $actual ); + + + } + + function test_add_attachment_field_get_unequal_context() { + + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $_GET['post_id'] = $post_id; + $id = 123; + $post_type = 'post'; + + $mpt = new MultiPostThumbnails( array( 'id' => $id, 'label' => 'thelabel', 'post_type' => $post_type ) ); + + $add_attachment_field = $mpt->add_attachment_field( array(), $post ); + + $this->assertArrayHasKey( $post_type . '-' . $id . '-thumbnail', $add_attachment_field ); + + + } + + function test_add_attachment_field_get() { + + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $_GET['post_id'] = $post_id; + $id = 123; + $post_type = 'post'; + + $mpt = new MultiPostThumbnails( array( 'id' => $id, 'label' => 'thelabel', 'post_type' => $post_type ) ); + + $add_attachment_field = $mpt->add_attachment_field( array(), $post ); + + $this->assertArrayHasKey( $post_type . '-' . $id . '-thumbnail', $add_attachment_field ); + + + } + + function test_add_attachment_field_post() { + + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $post2 = $this->factory->post->create_and_get( array( 'post_parent' => $post_id ) ); + $_POST = array(1,2,3); + $id = 123; + $post_type = 'post'; + + $mpt = new MultiPostThumbnails( array( 'id' => $id, 'label' => 'thelabel', 'post_type' => $post_type ) ); + + $add_attachment_field = $mpt->add_attachment_field( array(), $post2 ); + + $this->assertArrayHasKey( $post_type . '-' . $id . '-thumbnail', $add_attachment_field ); + + } + + +} + From e85df9a31e4f65b5889edad561925a6958f606c2 Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Tue, 9 Sep 2014 17:29:15 -0400 Subject: [PATCH 02/29] restructure original class to make it testable, hit 100% coverage* (with cc ignores) --- multi-post-thumbnails.php | 98 +++- tests/test-multi-post-thumbnails.php | 648 ++++++++++++++++++++++++++- 2 files changed, 729 insertions(+), 17 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 5e89682..bd9cdda 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -36,6 +36,10 @@ class MultiPostThumbnails { protected $priority; protected $context; + + /** + * @codeCoverageIgnore + */ public function __construct($args = array()) { $this->register($args); } @@ -229,7 +233,7 @@ public function action_delete_attachment($post_id) { * @return boolean */ public function filter_is_protected_meta($protected, $meta_key) { - if (apply_filters('mpt_unprotect_meta', false)) { + if ($this->apply_filters('mpt_unprotect_meta', false)) { return $protected; } @@ -246,6 +250,8 @@ public function filter_is_protected_meta($protected, $meta_key) { * @param string $relative_path Relative file path to the plugin file to get the URL of * @param string $plugin_path Absolute file path to the plugin base directory * @return string the URL of the plugin file + * + * @codeCoverageIgnore internal method */ private function plugins_url($relative_path, $plugin_path) { $template_dir = get_template_directory(); @@ -355,7 +361,9 @@ public static function get_post_thumbnail_id($post_type, $id, $post_id) { */ public static function get_post_thumbnail_url($post_type, $id, $post_id = 0, $size = null) { if (!$post_id) { + $post_id = get_the_ID(); + } $post_thumbnail_id = self::get_post_thumbnail_id($post_type, $id, $post_id); @@ -378,12 +386,14 @@ public static function get_post_thumbnail_url($post_type, $id, $post_id = 0, $si * * @param string $thumbnail_id The thumbnail's post ID. * @return string HTML + * + * @codeCoverageIgnore since this can't be accessed externally (protected) */ protected function post_thumbnail_html($thumbnail_id = null) { global $content_width, $_wp_additional_image_sizes, $post_ID, $wp_version; $url_class = ""; - $ajax_nonce = wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); + $ajax_nonce = $this->wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); if ($this->version_compare($wp_version, '3.5', '<')) { // Use the old thickbox for versions prior to 3.5 @@ -434,30 +444,31 @@ protected function post_thumbnail_html($thumbnail_id = null) { * Set/remove the post thumbnail. AJAX handler. * * @return string Updated post thumbnail HTML. + * */ public function set_thumbnail() { global $post_ID; // have to do this so get_upload_iframe_src() can grab it $post_ID = intval($_POST['post_id']); if ( !current_user_can('edit_post', $post_ID)) - die('-1'); + return $this->mpt_die('-1'); $thumbnail_id = intval($_POST['thumbnail_id']); - check_ajax_referer("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); + $this->check_ajax_referer("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); if ($thumbnail_id == '-1') { delete_post_meta($post_ID, $this->get_meta_key()); - die($this->post_thumbnail_html(null)); + return $this->mpt_die($this->post_thumbnail_html(null)); } if ($thumbnail_id && get_post($thumbnail_id)) { - $thumbnail_html = wp_get_attachment_image($thumbnail_id, 'thumbnail'); + $thumbnail_html = $this->wp_get_attachment_image($thumbnail_id, 'thumbnail'); if (!empty($thumbnail_html)) { - $this->set_meta($post_ID, $this->post_type, $this->id, $thumbnail_id); - die($this->post_thumbnail_html($thumbnail_id)); + self::set_meta($post_ID, $this->post_type, $this->id, $thumbnail_id); + return $this->mpt_die($this->post_thumbnail_html($thumbnail_id)); } } - die('0'); + return $this->mpt_die('0'); } /** @@ -571,6 +582,14 @@ public function wp_parse_args( $args, $defaults = '' ){ } + /** + * Helper method to assist mocking/testing of a global function + * + * @param $status + * + * @return mixed + * @codeCoverageIgnore + */ public function wp_create_nonce( $action ){ return wp_create_nonce( $action ); @@ -594,6 +613,67 @@ public function get_post( $post = null, $output = OBJECT, $filter = 'raw' ){ } + /** + * Helper method to assist mocking/testing of a global function + * + * @param $tag + * @param $value + * + * @return mixed|void + * + * @codeCoverageIgnore + */ + public function apply_filters( $tag, $value ){ + + return apply_filters( $tag, $value ); + + } + + /** + * Helper method to assist mocking/testing of a global function + * + * @param $action + * @param bool $query_arg + * @param bool $die + * + * @return bool + * @codeCoverageIgnore + */ + public function check_ajax_referer( $action = -1, $query_arg = false, $die = true ){ + + return check_ajax_referer( $action, $query_arg, $die ); + + } + + /** + * Helper method to assist mocking/testing of a global function (die, which is a keyword) + * + * @param $status + * + * @return mixed + * @codeCoverageIgnore + */ + public function mpt_die( $status ){ + if ( ! defined('WP_TEST_ENVIRONMENT') || WP_TEST_ENVIRONMENT === false ){ + die( $status ); + } + return $status; + } + + /** + * Helper method to assist mocking/testing of a global function + * + * @param $status + * + * @return mixed + * @codeCoverageIgnore + */ + public function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = ''){ + + return wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = ''); + + } + } diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 71c22d3..772be7a 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -1,7 +1,7 @@ 'foo', 'id' => 'bar', 'post_type' => 'post' ) ); @@ -83,7 +87,9 @@ function test_get_meta_key() { } - + /** + * @covers MultiPostThumbnails::add_metabox + */ function test_add_metabox() { global $wp_meta_boxes; @@ -96,6 +102,9 @@ function test_add_metabox() { } + /** + * @covers MultiPostThumbnails::thumbnail_meta_box + */ function test_thumbnail_meta_box() { $post_id = 123; @@ -124,6 +133,9 @@ function test_thumbnail_meta_box() { } + /** + * @covers MultiPostThumbnails::add_attachment_field + */ function test_add_attachment_field_none() { $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) @@ -148,6 +160,9 @@ function test_add_attachment_field_none() { } + /** + * @covers MultiPostThumbnails::add_attachment_field + */ function test_add_attachment_field_get_calling_post_id_null() { $_GET['post_id'] = 123; @@ -174,6 +189,9 @@ function test_add_attachment_field_get_calling_post_id_null() { } + /** + * @covers MultiPostThumbnails::add_attachment_field + */ function test_add_attachment_field_get_unsupported_post_type() { $_GET['post_id'] = 123; @@ -201,6 +219,9 @@ function test_add_attachment_field_get_unsupported_post_type() { } + /** + * @covers MultiPostThumbnails::add_attachment_field + */ function test_add_attachment_field_get_unequal_context() { $post = $this->factory->post->create_and_get(); @@ -218,6 +239,9 @@ function test_add_attachment_field_get_unequal_context() { } + /** + * @covers MultiPostThumbnails::add_attachment_field + */ function test_add_attachment_field_get() { $post = $this->factory->post->create_and_get(); @@ -235,14 +259,17 @@ function test_add_attachment_field_get() { } + /** + * @covers MultiPostThumbnails::add_attachment_field + */ function test_add_attachment_field_post() { - $post = $this->factory->post->create_and_get(); - $post_id = $post->ID; - $post2 = $this->factory->post->create_and_get( array( 'post_parent' => $post_id ) ); - $_POST = array(1,2,3); - $id = 123; - $post_type = 'post'; + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $post2 = $this->factory->post->create_and_get( array( 'post_parent' => $post_id ) ); + $_POST = array( 1, 2, 3 ); + $id = 123; + $post_type = 'post'; $mpt = new MultiPostThumbnails( array( 'id' => $id, 'label' => 'thelabel', 'post_type' => $post_type ) ); @@ -252,6 +279,611 @@ function test_add_attachment_field_post() { } + /** + * @covers MultiPostThumbnails::enqueue_admin_scripts + */ + function test_enqueue_admin_scripts_wp_version_34() { + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'version_compare' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'version_compare' ) + ->will( $this->returnValue( true ) ); + + $mpt->enqueue_admin_scripts( 'post-new.php' ); + + $this->assertTrue( wp_script_is( 'thickbox' ) ); + $this->assertTrue( wp_script_is( 'mpt-featured-image' ) ); + + } + + /** + * @covers MultiPostThumbnails::enqueue_admin_scripts + */ + function test_enqueue_admin_scripts_wp_version_40() { + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'version_compare' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'version_compare' ) + ->will( $this->returnValue( false ) ); + + $mpt->enqueue_admin_scripts( 'post-new.php' ); + + $this->assertTrue( wp_script_is( 'mpt-featured-image' ) ); + $this->assertTrue( wp_script_is( 'mpt-featured-image-modal' ) ); + $this->assertTrue( wp_script_is( 'media-editor' ) ); + + } + + + /** + * @covers MultiPostThumbnails::enqueue_admin_scripts + */ + function test_enqueue_admin_scripts_not_in_hook_array() { + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'version_compare' ) ) + ->getMock(); + + $mpt->expects( $this->never() ) + ->method( 'version_compare' ); + + $mpt->enqueue_admin_scripts( 'NOTINARRAY' ); + + } + + /** + * @covers MultiPostThumbnails::admin_header_scripts + */ + function test_admin_header_scripts() { + + $post = $this->factory->post->create_and_get(); + $post->ID = 10000; + $GLOBALS['post'] = $post; + $mpt = new MultiPostThumbnails; + ob_start(); + $mpt->admin_header_scripts(); + $output = ob_get_clean(); + $this->assertEquals( '', $output ); + + } + + /** + * @covers MultiPostThumbnails::action_delete_attachment + */ + function test_action_delete_attachment() { + + $post_id = $this->factory->post->create(); + $meta_key = 'foobar'; + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->exactly( 4 ) ) + ->method( 'get_meta_key' ) + ->will( $this->returnValue( $meta_key ) ); + + global $wpdb; + + $wpdb->query( $wpdb->prepare( "INSERT INTO $wpdb->postmeta ( meta_key, meta_value ) values ( '%s', %d )", $mpt->get_meta_key(), $post_id ) ); + + $result = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->postmeta WHERE meta_key = '%s' AND meta_value = %d", $mpt->get_meta_key(), $post_id ) ); + $this->assertEquals( 1, count( $result ) ); + $mpt->action_delete_attachment( $post_id ); + $result = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->postmeta WHERE meta_key = '%s' AND meta_value = %d", $mpt->get_meta_key(), $post_id ) ); + $this->assertEquals( 0, count( $result ) ); + + } + + /** + * @covers MultiPostThumbnails::filter_is_protected_meta + */ + function test_filter_is_protected_meta_filter_returns_true() { + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'apply_filters' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'apply_filters' ) + ->with( $this->equalTo( 'mpt_unprotect_meta' ), $this->equalTo( false ) ) + ->will( $this->returnValue( true ) ); + + $expected = 'foo'; + $actual = $mpt->filter_is_protected_meta( $expected, 'bar' ); + + $this->assertEquals( $expected, $actual ); + + + } + + /** + * @covers MultiPostThumbnails::filter_is_protected_meta + */ + function test_filter_is_protected_meta_filter_meta_key_equals() { + + $meta_key = 'bar'; + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'apply_filters', 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'apply_filters' ) + ->with( $this->equalTo( 'mpt_unprotect_meta' ), $this->equalTo( false ) ) + ->will( $this->returnValue( false ) ); + + $mpt->expects( $this->once() ) + ->method( 'get_meta_key' ) + ->will( $this->returnValue( $meta_key ) ); + + $expected = 'foo'; + $actual = $mpt->filter_is_protected_meta( $expected, $meta_key ); + + $this->assertTrue( $actual ); + + + } + + /** + * @covers MultiPostThumbnails::filter_is_protected_meta + */ + function test_filter_is_protected_meta_filter_meta_key_not_equals() { + + $meta_key = 'bar'; + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'apply_filters', 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'apply_filters' ) + ->with( $this->equalTo( 'mpt_unprotect_meta' ), $this->equalTo( false ) ) + ->will( $this->returnValue( false ) ); + + $mpt->expects( $this->once() ) + ->method( 'get_meta_key' ) + ->will( $this->returnValue( 'not meta key' ) ); + + $expected = 'foo'; + $actual = $mpt->filter_is_protected_meta( $expected, $meta_key ); + + $this->assertEquals( $actual, $expected ); + + + } + + /** + * @covers MultiPostThumbnails::has_post_thumbnail + */ + function test_has_post_thumbnail() { + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $id = 'bar'; + $expected = 'foz'; + + update_post_meta( $post->ID, 'post_' . $id . '_thumbnail_id', $expected ); + + $GLOBALS['post'] = $post; + $actual = MultiPostThumbnails::has_post_thumbnail( 'post', $id ); + + $this->assertEquals( $actual, $expected ); + + } + + /** + * @covers MultiPostThumbnails::has_post_thumbnail + */ + function test_has_post_thumbnail_no_post_id() { + + $actual = MultiPostThumbnails::has_post_thumbnail( 'post', 'foz' ); + + $this->assertFalse( $actual ); + + } + + /** + * @covers MultiPostThumbnails::get_the_post_thumbnail + */ + function test_get_the_post_thumbnail_set_meta() { + + $thumbnail_id = 'foobar'; + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = $this->factory->attachment->create_object( 'foo.jpg', $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + + MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); + + $actual = MultiPostThumbnails::get_the_post_thumbnail( 'post', $thumbnail_id, $post->ID, 'post-thumbnail', '', true ); + + $image_link = wp_get_attachment_image( $attachment_id, 'post-thumbnail', false, '' ); + $url = wp_get_attachment_url( $attachment_id ); + $expected = sprintf( '%s', $url, $image_link ); + + $this->assertEquals( $actual, $expected ); + + + } + + /** + * @covers MultiPostThumbnails::get_the_post_thumbnail + */ + function test_get_the_post_thumbnail_unset_meta() { + + $thumbnail_id = 'foobar'; + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $actual = MultiPostThumbnails::get_the_post_thumbnail( 'post', $thumbnail_id, $post->ID, 'post-thumbnail', '', true ); + $expected = null; + $this->assertEquals( $actual, $expected ); + + } + + /** + * @covers MultiPostThumbnails::the_post_thumbnail + */ + function test_the_post_thumbnail() { + + $thumbnail_id = 'foobar'; + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + + + $expected = MultiPostThumbnails::get_the_post_thumbnail( 'post', $thumbnail_id, $post->ID, 'post-thumbnail', '', true ); + + ob_start(); + MultiPostThumbnails::the_post_thumbnail( 'post', $thumbnail_id, $post->ID, $post->ID, 'post-thumbnail', '', true ); + $actual = ob_get_clean(); + + $this->assertEquals( $actual, $expected ); + + + } + + /** + * @covers MultiPostThumbnails::get_post_thumbnail_id + */ + + public function test_get_post_thumbnail_id(){ + + $post_type = 'page'; + $thumbnail_id = 'foo'; + $thumbnail_post_id = 'bar'; + $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); + MultiPostThumbnails::set_meta( $post_id, $post_type, $thumbnail_id, $thumbnail_post_id); + + $actual = MultiPostThumbnails::get_post_thumbnail_id( $post_type, $thumbnail_id, $post_id ); + + $this->assertEquals( $thumbnail_post_id, $actual ); + + } + + /** + * @covers MultiPostThumbnails::get_post_thumbnail_url + */ + public function test_get_post_thumbnail_url() { + + $post = $this->factory->post->create_and_get(); + $GLOBALS['post'] = $post; + $thumbnail_id = 'foobar'; + $file_name = 'foo.jpg'; + + $attachment_id = $this->factory->attachment->create_object( $file_name, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + + MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); + + $upload_dir_raw = wp_upload_dir(); + $upload_url = str_replace( $upload_dir_raw['subdir'], '', $upload_dir_raw['url'] ); //strip out the month/date from URL + + $expected = $upload_url . '/' . $file_name; + + + $actual = MultiPostThumbnails::get_post_thumbnail_url( 'post', $thumbnail_id ); + + $this->assertEquals( $actual, $expected ); + + + } + + /** + * @covers MultiPostThumbnails::get_post_thumbnail_url + */ + public function test_get_post_thumbnail_url_size() { + + $post = $this->factory->post->create_and_get(); + $GLOBALS['post'] = $post; + $thumbnail_id = 'foobar'; + $file_name = 'foo.jpg'; + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = $this->factory->attachment->create_object( $file_name, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + + MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); + + $upload_dir_raw = wp_upload_dir(); + $upload_url = str_replace( $upload_dir_raw['subdir'], '', $upload_dir_raw['url'] ); //strip out the month/date from URL + + $expected = $upload_url . '/' . $file_name; + + $actual = MultiPostThumbnails::get_post_thumbnail_url( 'post', $thumbnail_id, $post->ID, 'size' ); + + $this->assertEquals( $actual, $expected ); + + + } + + /** + * @covers MultiPostThumbnails::get_post_thumbnail_url + */ + public function test_get_post_thumbnail_url_size_no_attachment() { + + $post = $this->factory->post->create_and_get(); + $GLOBALS['post'] = $post; + $thumbnail_id = 'foobar'; + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = null; + + MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); + + $upload_dir_raw = wp_upload_dir(); + $upload_url = str_replace( $upload_dir_raw['subdir'], '', $upload_dir_raw['url'] ); //strip out the month/date from URL + + $expected = ''; + + $actual = MultiPostThumbnails::get_post_thumbnail_url( 'post', $thumbnail_id, $post->ID, 'size' ); + $this->assertEquals( $actual, $expected ); + + } + + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + public function test_set_thumbnail_current_user_cannot() { + + $post_id = $this->factory->post->create(); + $_POST['post_id'] = $post_id; + + $user_id = $this->factory->user->create( array( 'role' => 'subscriber' ) ); + wp_set_current_user( $user_id ); + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'mpt_die', 'check_ajax_referer', 'set_meta', 'post_thumbnail_html', 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'mpt_die' ) + ->with( $this->equalTo( '-1' ) ); + + $mpt->expects( $this->never() ) + ->method( 'check_ajax_referer' ); + + $mpt->expects( $this->never() ) + ->method( 'set_meta' ); + + $mpt->expects( $this->never() ) + ->method( 'get_meta_key' ); + + $mpt->expects( $this->never() ) + ->method( 'post_thumbnail_html' ); + + + $mpt->set_thumbnail(); + + } + + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + public function test_set_thumbnail_current_user_can_thumbnail_negative_1() { + + $post_id = $this->factory->post->create(); + $_POST['post_id'] = $post_id; + $_POST['thumbnail_id'] = '-1'; + $id = null; + $post_type = null; + + $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); + wp_set_current_user( $user_id ); + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'check_ajax_referer', 'set_meta', 'get_meta_key' ) ) + ->getMock(); + + + $mpt->expects( $this->once() ) + ->method( 'get_meta_key' ); + + $mpt->expects( $this->once() ) + ->method( 'check_ajax_referer' ); + + $mpt->expects( $this->never() ) + ->method( 'set_meta' ); + + + $result = $mpt->set_thumbnail(); + + + $document = new DOMDocument; + $document->preserveWhiteSpace = false; + $document->loadHTML( $result ); + $xpath = new DOMXPath ( $document ); + $anchor_tag = $xpath->query( "//a[@id='set-" . $post_type . "-" . $id . "-thumbnail']" ); + $this->assertEquals( 1, $anchor_tag->length ); + + + } + + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + public function test_set_thumbnail_current_user_can_thumbnail_not_a_post() { + + $post_id = $this->factory->post->create(); + $_POST['post_id'] = $post_id; + $_POST['thumbnail_id'] = 'notapostid'; + + $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); + wp_set_current_user( $user_id ); + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'mpt_die', 'check_ajax_referer', 'set_meta', 'post_thumbnail_html', 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'mpt_die' ) + ->with( $this->equalTo( '0' ) ); + + $mpt->expects( $this->once() ) + ->method( 'check_ajax_referer' ); + + $mpt->expects( $this->never() ) + ->method( 'set_meta' ); + + $mpt->expects( $this->never() ) + ->method( 'get_meta_key' ); + + $mpt->expects( $this->never() ) + ->method( 'post_thumbnail_html' ); + + + $mpt->set_thumbnail(); + + + } + + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + public function test_set_thumbnail_is_a_post() { + + $post_type = 'post'; + $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); + $attachment_id = $this->factory->attachment->create_object( 'foo.jpg', $post_id, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + + $id = 'barfoo'; + $_POST['post_id'] = $post_id; + $_POST['thumbnail_id'] = $attachment_id; + + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'check_ajax_referer', 'get_meta_key' ) ) + ->getMock(); + + $mpt->register( array( 'label' => 'foobar', 'id' => $id ) ); + + + $mpt->expects( $this->once() ) + ->method( 'check_ajax_referer' ); + + $mpt->expects( $this->never() ) + ->method( 'get_meta_key' ); + + + $result = $mpt->set_thumbnail(); + + + $document = new DOMDocument; + $document->preserveWhiteSpace = false; + $document->loadHTML( $result ); + $xpath = new DOMXPath ( $document ); + $anchor_tag = $xpath->query( "//a[@id='set-" . $post_type . "-" . $id . "-thumbnail']" ); + $this->assertEquals( 1, $anchor_tag->length ); + + } + + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + public function test_set_thumbnail_is_a_post_thumbnail_html_returns_null() { + + $post_type = 'post'; + $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); + $attachment_id = $this->factory->attachment->create_object( 'foo.jpg', $post_id, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + + $id = 'barfoo'; + $_POST['post_id'] = $post_id; + $_POST['thumbnail_id'] = $attachment_id; + + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'mpt_die', 'check_ajax_referer', 'get_meta_key', 'wp_get_attachment_image' ) ) + ->getMock(); + + $mpt->register( array( 'label' => 'foobar', 'id' => $id ) ); + + + $mpt->expects( $this->once() ) + ->method( 'check_ajax_referer' ); + + $mpt->expects( $this->never() ) + ->method( 'get_meta_key' ); + + $mpt->expects( $this->once() ) + ->method( 'wp_get_attachment_image' ) + ->will( $this->returnValue( null ) ); + + $mpt->expects( $this->once() ) + ->method( 'mpt_die' ) + ->with( $this->equalTo( '0' ) ); + + + $mpt->set_thumbnail(); + + } + + + /** + * @covers MultiPostThumbnails::set_meta + */ + public function test_set_meta() { + + $post_type = 'page'; + $thumbnail_id = 'foo'; + $thumbnail_post_id = 'bar'; + $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); + MultiPostThumbnails::set_meta( $post_id, $post_type, $thumbnail_id, $thumbnail_post_id); + + $actual = get_post_meta( $post_id, "{$post_type}_{$thumbnail_id}_thumbnail_id", true ); + + $this->assertEquals( $thumbnail_post_id, $actual ); + + } + } + From bd31aa696ce60e916446b85500b16d6030cd8a29 Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Fri, 12 Sep 2014 10:38:17 -0400 Subject: [PATCH 03/29] fix copypasta issues with phpdoc in helper methods --- multi-post-thumbnails.php | 11 +++++++---- tests/test-multi-post-thumbnails.php | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index bd9cdda..489f385 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -585,9 +585,9 @@ public function wp_parse_args( $args, $defaults = '' ){ /** * Helper method to assist mocking/testing of a global function * - * @param $status + * @param $action * - * @return mixed + * @return string * @codeCoverageIgnore */ public function wp_create_nonce( $action ){ @@ -663,9 +663,12 @@ public function mpt_die( $status ){ /** * Helper method to assist mocking/testing of a global function * - * @param $status + * @param $attachment_id + * @param string $size + * @param bool $icon + * @param string $attr * - * @return mixed + * @return string * @codeCoverageIgnore */ public function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = ''){ diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 772be7a..2ccff5a 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -489,8 +489,9 @@ function test_has_post_thumbnail() { */ function test_has_post_thumbnail_no_post_id() { + $post = $this->factory->post->create_and_get(); + $_POST['post'] = $post; $actual = MultiPostThumbnails::has_post_thumbnail( 'post', 'foz' ); - $this->assertFalse( $actual ); } From 20b01fb693d0e7596d600abeb18ef8ed44f4b42d Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Fri, 12 Sep 2014 10:46:56 -0400 Subject: [PATCH 04/29] set post key in superglobal --- tests/test-multi-post-thumbnails.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 2ccff5a..4d71784 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -491,6 +491,7 @@ function test_has_post_thumbnail_no_post_id() { $post = $this->factory->post->create_and_get(); $_POST['post'] = $post; + $_GLOBALS['post'] = $post; $actual = MultiPostThumbnails::has_post_thumbnail( 'post', 'foz' ); $this->assertFalse( $actual ); From 14b36d0d4cfd384c5d32c59cc3256b5a2a2ee816 Mon Sep 17 00:00:00 2001 From: YMat Gargano Date: Fri, 12 Sep 2014 15:01:35 +0000 Subject: [PATCH 05/29] fix for test issues --- tests/test-multi-post-thumbnails.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 4d71784..dc05f29 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -489,10 +489,7 @@ function test_has_post_thumbnail() { */ function test_has_post_thumbnail_no_post_id() { - $post = $this->factory->post->create_and_get(); - $_POST['post'] = $post; - $_GLOBALS['post'] = $post; - $actual = MultiPostThumbnails::has_post_thumbnail( 'post', 'foz' ); + $actual = MultiPostThumbnails::has_post_thumbnail( 'post', 'foz', false ); $this->assertFalse( $actual ); } From 400c1440bd2292c611d495c4d7d08a98361a1fba Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Fri, 12 Sep 2014 14:54:36 -0400 Subject: [PATCH 06/29] update versions of wordpress to 3.8.4, 3.9.2, 4.0 and latest --- .travis.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 64be0af..c68bb3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,12 @@ php: env: - WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 - - WP_VERSION=3.8 WP_MULTISITE=0 - - WP_VERSION=3.8 WP_MULTISITE=1 + - WP_VERSION=4.0 WP_MULTISITE=0 + - WP_VERSION=4.0 WP_MULTISITE=1 + - WP_VERSION=3.9.2 WP_MULTISITE=0 + - WP_VERSION=3.9.2 WP_MULTISITE=1 + - WP_VERSION=3.8.4 WP_MULTISITE=0 + - WP_VERSION=3.8.4 WP_MULTISITE=1 before_script: - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION From 019f3aa13294114f6ad05ded8ff19b53ddab5369 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 15:44:58 -0400 Subject: [PATCH 07/29] Make the tests installer executable. --- bin/install-wp-tests.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/install-wp-tests.sh diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh old mode 100644 new mode 100755 From 48eb2e5a1f3d04df262af783993244cec19b16aa Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 16:01:37 -0400 Subject: [PATCH 08/29] Add trigger_error() testing from http://www.sitepoint.com/testing-error-conditions-with-phpunit/ --- tests/test-multi-post-thumbnails.php | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index dc05f29..0ed46e9 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -3,6 +3,48 @@ class TestMultiPostThumbnails extends WP_UnitTestCase { + private $errors; + + public function setUp() { + + parent::setUp(); + + $this->errors = array(); + + set_error_handler( array( $this, 'errorHandler' ) ); + + } + + public function errorHandler( $errno, $errstr, $errfile, $errline, $errcontext ) { + + $this->errors[] = compact( + 'errno', + 'errstr', + 'errfile', + 'errline', + 'errcontext' + ); + + } + + public function assertError( $errstr, $errno ) { + + foreach ( $this->errors as $error ) { + + if ( ( $errstr === $error['errstr'] ) && ( $errno === $error['errno'] ) ) { + + return; + + } + + } + + $fail_message = sprintf( 'Error with level %s and message "%s" not found in %s', $errno, $errstr, var_export( $this->errors, true ) ); + + $this->fail( $fail_message ); + + } + function provider_test_register() { return array( From d4fc7b531e93f6a50202afc281beda6fee175ff2 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 16:30:27 -0400 Subject: [PATCH 09/29] =?UTF-8?q?Add=20default=20for=20assertError=20using?= =?UTF-8?q?=20PHP=E2=80=99s=20default=20error=20number.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test-multi-post-thumbnails.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 0ed46e9..b72d59f 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -27,7 +27,7 @@ public function errorHandler( $errno, $errstr, $errfile, $errline, $errcontext ) } - public function assertError( $errstr, $errno ) { + public function assertError( $errstr, $errno = E_USER_NOTICE ) { foreach ( $this->errors as $error ) { From bf2f3512ec4a7c9c789a8502f0448c2af7a1c6f8 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 16:30:53 -0400 Subject: [PATCH 10/29] Remove trigger_error() wrapper and refactor test. --- multi-post-thumbnails.php | 36 +++++++++------------------- tests/test-multi-post-thumbnails.php | 12 +++++----- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 489f385..91dcd25 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -79,17 +79,15 @@ public function register($args = array()) { $this->args = wp_parse_args($args, $defaults); // Create and set properties - foreach( $this->args as $k => $v ) { $this->$k = $v; } - - // Need these args to be set at a minimum if (null === $this->label || null === $this->id) { - if ( WP_DEBUG ) { - $this->trigger_error(sprintf(__("The 'label' and 'id' values of the 'args' parameter of '%s::%s()' are required", 'multiple-post-thumbnails'), __CLASS__, __FUNCTION__)); + if ( WP_DEBUG ) { + $error_message = $this->get_register_required_field_error_message(); + trigger_error( $error_message ); } return; } @@ -112,6 +110,14 @@ public function register($args = array()) { } + public function get_register_required_field_error_message() { + + $error_format = __( "The 'label' and 'id' values of the 'args' parameter of '%s::%s()' are required", 'multiple-post-thumbnails' ); + + return sprintf( $error_format, __CLASS__, __FUNCTION__ ); + + } + /** * get the meta key used to store a post's thumbnail * @@ -484,26 +490,6 @@ public static function set_meta($post_ID, $post_type, $thumbnail_id, $thumbnail_ return update_post_meta($post_ID, "{$post_type}_{$thumbnail_id}_thumbnail_id", $thumbnail_post_id); } - - /** - * Helper method to assist testing of a global function - * @param $error_msg - * @param int $error_type - * - * @return bool - * - * @codeCoverageIgnore - */ - function trigger_error( $error_msg, $error_type = E_USER_NOTICE ){ - - if ( ! defined('WP_TEST_ENVIRONMENT') || WP_TEST_ENVIRONMENT === false ){ - - return trigger_error( $error_msg, $error_type ); - - } - - } - /** * Helper method to assist mocking/testing of a global function * @param $feature diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index b72d59f..8e731ae 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -69,7 +69,7 @@ function test_register( $current_theme_supports, $add_theme_support, $version_co $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) ->disableOriginalConstructor() - ->setMethods( array( 'version_compare', 'current_theme_supports', 'trigger_error', 'add_theme_support' ) ) + ->setMethods( array( 'version_compare', 'current_theme_supports', 'add_theme_support' ) ) ->getMock(); $mpt->expects( $this->exactly( $current_theme_supports_expects ) ) @@ -84,15 +84,15 @@ function test_register( $current_theme_supports, $add_theme_support, $version_co ->method( 'version_compare' ) ->will( $this->returnValue( $version_compare ) ); - if ( ! $id || ! $label ) { + $mpt->register( array( 'label' => $label, 'id' => $id ) ); - $mpt->expects( $this->once() ) - ->method( 'trigger_error' ); + if ( ! $id || ! $label ) { - } + $expected_error_msg = $mpt->get_register_required_field_error_message(); + $this->assertError( $expected_error_msg ); - $mpt->register( array( 'label' => $label, 'id' => $id ) ); + } if ( $assertFilters ) { From e77380166fde6d934f24933c663cf7fceec0dd07 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 16:42:59 -0400 Subject: [PATCH 11/29] Move logic for adding theme support and attaching hooks into separate functions. --- multi-post-thumbnails.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 91dcd25..1c5e3c3 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -92,11 +92,25 @@ public function register($args = array()) { return; } + $this->add_theme_support(); + + $this->attach_hooks(); + + } + + public function add_theme_support() { + // add theme support if not already added - if ( ! $this->current_theme_supports('post-thumbnails')) { - $this->add_theme_support( 'post-thumbnails' ); + if ( ! current_theme_supports( 'post-thumbnails' ) ) { + + add_theme_support( 'post-thumbnails' ); + } + } + + public function attach_hooks() { + add_action('add_meta_boxes', array($this, 'add_metabox')); if ( $this->version_compare($wp_version, '3.5', '<')) { add_filter('attachment_fields_to_edit', array($this, 'add_attachment_field'), 20, 2); From 796d542008de27f7babcdcbc15dd404bd8d5c257 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 16:43:30 -0400 Subject: [PATCH 12/29] Remove all functions that simply wrap WP core functions. --- multi-post-thumbnails.php | 159 -------------------------------------- 1 file changed, 159 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 1c5e3c3..85f3442 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -504,147 +504,6 @@ public static function set_meta($post_ID, $post_type, $thumbnail_id, $thumbnail_ return update_post_meta($post_ID, "{$post_type}_{$thumbnail_id}_thumbnail_id", $thumbnail_post_id); } - /** - * Helper method to assist mocking/testing of a global function - * @param $feature - * - * @return bool - * - * @codeCoverageIgnore - */ - function add_theme_support( $feature ) { - - return add_theme_support( $feature ); - - } - - /** - * Helper method to assist mocking/testing of a global function - * @param $feature - * - * @return bool - * - * @codeCoverageIgnore - */ - function current_theme_supports( $feature ) { - - return current_theme_supports( $feature ); - - } - - /** - * Helper method to assist mocking/testing of a global function - * @param $version1 - * @param $version2 - * @param null $operator - * - * @return mixed - * - * @codeCoverageIgnorep - */ - public function version_compare ( $version1, $version2, $operator = null ) { - - return version_compare( $version1, $version2, $operator ); - - } - - - /** - * Helper method to assist mocking/testing of a global function - * @param $post_id - * @param string $key - * @param bool $single - * - * @return mixed - * - * @codeCoverageIgnore - */ - public function get_post_meta( $post_id, $key = '', $single = false ) { - - return get_post_meta( $post_id, $key, $single ); - - } - - - /** - * Helper method to assist mocking/testing of a global function - * - * @param $args - * @param string $defaults - * - * @return array - * - * @codeCoverageIgnore - */ - public function wp_parse_args( $args, $defaults = '' ){ - - return wp_parse_args( $args, $defaults ); - - } - - /** - * Helper method to assist mocking/testing of a global function - * - * @param $action - * - * @return string - * @codeCoverageIgnore - */ - public function wp_create_nonce( $action ){ - - return wp_create_nonce( $action ); - - } - - /** - * Helper method to assist mocking/testing of a global function - * - * @param null $post - * @param string $output - * @param string $filter - * - * @return null|WP_Post - * - * @codeCoverageIgnore - */ - public function get_post( $post = null, $output = OBJECT, $filter = 'raw' ){ - - return get_post( $post, $output, $filter ); - - } - - /** - * Helper method to assist mocking/testing of a global function - * - * @param $tag - * @param $value - * - * @return mixed|void - * - * @codeCoverageIgnore - */ - public function apply_filters( $tag, $value ){ - - return apply_filters( $tag, $value ); - - } - - /** - * Helper method to assist mocking/testing of a global function - * - * @param $action - * @param bool $query_arg - * @param bool $die - * - * @return bool - * @codeCoverageIgnore - */ - public function check_ajax_referer( $action = -1, $query_arg = false, $die = true ){ - - return check_ajax_referer( $action, $query_arg, $die ); - - } - /** * Helper method to assist mocking/testing of a global function (die, which is a keyword) * @@ -660,24 +519,6 @@ public function mpt_die( $status ){ return $status; } - /** - * Helper method to assist mocking/testing of a global function - * - * @param $attachment_id - * @param string $size - * @param bool $icon - * @param string $attr - * - * @return string - * @codeCoverageIgnore - */ - public function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = ''){ - - return wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = ''); - - } - - } if ( is_admin() ) From 63680e81f1596424fb095be6f4c9ca38d95d8971 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 16:49:56 -0400 Subject: [PATCH 13/29] =?UTF-8?q?Don=E2=80=99t=20call=20(now=20nonexistent?= =?UTF-8?q?)=20WP=20core=20function=20wrappers.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- multi-post-thumbnails.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 85f3442..49bc776 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -66,8 +66,6 @@ public function __construct($args = array()) { */ public function register($args = array()) { - global $wp_version; - $defaults = array( 'label' => null, 'id' => null, @@ -111,8 +109,10 @@ public function add_theme_support() { public function attach_hooks() { + global $wp_version; + add_action('add_meta_boxes', array($this, 'add_metabox')); - if ( $this->version_compare($wp_version, '3.5', '<')) { + if ( version_compare( $wp_version, '3.5', '<' ) ) { add_filter('attachment_fields_to_edit', array($this, 'add_attachment_field'), 20, 2); } add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts')); @@ -182,19 +182,19 @@ public function add_attachment_field($form_fields, $post) { return $form_fields; // check the post type to see if link needs to be added - $calling_post = $this->get_post($calling_post_id); + $calling_post = get_post($calling_post_id); if (is_null($calling_post) || $calling_post->post_type != $this->post_type) { return $form_fields; } $referer = wp_get_referer(); - $query_vars = $this->wp_parse_args(parse_url($referer, PHP_URL_QUERY)); + $query_vars = wp_parse_args(parse_url($referer, PHP_URL_QUERY)); if( (isset($_REQUEST['context']) && $_REQUEST['context'] != $this->id) || (isset($query_vars['context']) && $query_vars['context'] != $this->id) ) return $form_fields; - $ajax_nonce = $this->wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$calling_post_id}"); + $ajax_nonce = wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$calling_post_id}"); $link = sprintf('' . __( 'Set as %3$s', 'multiple-post-thumbnails' ) . '', $this->id, $post->ID, $this->label, $this->post_type, $ajax_nonce); $form_fields["{$this->post_type}-{$this->id}-thumbnail"] = array( 'label' => $this->label, @@ -217,7 +217,7 @@ public function enqueue_admin_scripts( $hook ) { if ( ! in_array( $hook, array( 'post-new.php', 'post.php', 'media-upload-popup' ) ) ) return; - if ($this->version_compare($wp_version, '3.5', '<')) { + if (version_compare($wp_version, '3.5', '<')) { add_thickbox(); wp_enqueue_script( "mpt-featured-image", $this->plugins_url( 'js/multi-post-thumbnails-admin.js', __FILE__ ), array( 'jquery', 'media-upload' ) ); } else { // 3.5+ media modal @@ -253,7 +253,7 @@ public function action_delete_attachment($post_id) { * @return boolean */ public function filter_is_protected_meta($protected, $meta_key) { - if ($this->apply_filters('mpt_unprotect_meta', false)) { + if (apply_filters('mpt_unprotect_meta', false)) { return $protected; } @@ -413,9 +413,9 @@ protected function post_thumbnail_html($thumbnail_id = null) { global $content_width, $_wp_additional_image_sizes, $post_ID, $wp_version; $url_class = ""; - $ajax_nonce = $this->wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); + $ajax_nonce = wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); - if ($this->version_compare($wp_version, '3.5', '<')) { + if (version_compare($wp_version, '3.5', '<')) { // Use the old thickbox for versions prior to 3.5 $image_library_url = get_upload_iframe_src('image'); // if TB_iframe is not moved to end of query string, thickbox will remove all query args after it. @@ -453,7 +453,7 @@ protected function post_thumbnail_html($thumbnail_id = null) { $content_width = $old_content_width; } - if ($this->version_compare($wp_version, '3.5', '>=')) { + if (version_compare($wp_version, '3.5', '>=')) { $content .= sprintf('', $modal_js); } @@ -481,7 +481,7 @@ public function set_thumbnail() { } if ($thumbnail_id && get_post($thumbnail_id)) { - $thumbnail_html = $this->wp_get_attachment_image($thumbnail_id, 'thumbnail'); + $thumbnail_html = wp_get_attachment_image($thumbnail_id, 'thumbnail'); if (!empty($thumbnail_html)) { self::set_meta($post_ID, $this->post_type, $this->id, $thumbnail_id); return $this->mpt_die($this->post_thumbnail_html($thumbnail_id)); From a5346993f0f98eb8fb2d382d7e4c346331aa1ca1 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 16:59:06 -0400 Subject: [PATCH 14/29] Missed one call to a WP core function wrapper. --- multi-post-thumbnails.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 49bc776..8fdaa5d 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -158,7 +158,7 @@ public function add_metabox() { public function thumbnail_meta_box() { global $post; - $thumbnail_id = $this->get_post_meta($post->ID, $this->get_meta_key(), true); + $thumbnail_id = get_post_meta($post->ID, $this->get_meta_key(), true); echo $this->post_thumbnail_html($thumbnail_id); } From 26219959c052fb757bf5891dc6ad6176f9d04003 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sat, 13 Sep 2014 17:42:28 -0400 Subject: [PATCH 15/29] Separate argument parsing logic. --- multi-post-thumbnails.php | 53 ++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 8fdaa5d..1709db0 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -29,14 +29,12 @@ class MultiPostThumbnails { - protected $args; - public $label; - public $id; + public $label; + public $id; protected $post_type; protected $priority; protected $context; - /** * @codeCoverageIgnore */ @@ -64,30 +62,23 @@ public function __construct($args = array()) { * @param array|string $args See above description. * @return void */ - public function register($args = array()) { + public function register( $args = array() ) { - $defaults = array( - 'label' => null, - 'id' => null, - 'post_type' => 'post', - 'priority' => 'low', - 'context' => 'side', - ); + $this->parse_arguments( $args ); - $this->args = wp_parse_args($args, $defaults); - - // Create and set properties - foreach( $this->args as $k => $v ) { - $this->$k = $v; - } + // "label" and "id" are required + if ( is_null( $this->label ) || is_null( $this->id ) ) { - // Need these args to be set at a minimum - if (null === $this->label || null === $this->id) { if ( WP_DEBUG ) { + $error_message = $this->get_register_required_field_error_message(); + trigger_error( $error_message ); + } + return; + } $this->add_theme_support(); @@ -96,6 +87,28 @@ public function register($args = array()) { } + public function parse_arguments( $args ) { + + $defaults = array( + 'label' => null, + 'id' => null, + 'post_type' => 'post', + 'priority' => 'low', + 'context' => 'side', + ); + + $args = wp_parse_args( $args, $defaults ); + + $args = array_intersect_key( $args, $defaults ); + + foreach ( $args as $k => $v ) { + + $this->$k = $v; + + } + + } + public function add_theme_support() { // add theme support if not already added From 67c22e0f8fec94fc9d7a81fbe8120519fb5ecb60 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 11:52:20 -0400 Subject: [PATCH 16/29] Having parse_arguments() logic separate from register() is difficult for testing and unnecessary. --- multi-post-thumbnails.php | 43 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 1709db0..c6ed86b 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -64,18 +64,29 @@ public function __construct($args = array()) { */ public function register( $args = array() ) { - $this->parse_arguments( $args ); + // parse arugments and set defaults + $defaults = array( + 'label' => null, + 'id' => null, + 'post_type' => 'post', + 'priority' => 'low', + 'context' => 'side', + ); - // "label" and "id" are required - if ( is_null( $this->label ) || is_null( $this->id ) ) { + $args = wp_parse_args( $args, $defaults ); + + $args = array_intersect_key( $args, $defaults ); - if ( WP_DEBUG ) { + foreach ( $args as $k => $v ) { - $error_message = $this->get_register_required_field_error_message(); + $this->$k = $v; - trigger_error( $error_message ); + } - } + // "label" and "id" are required + if ( is_null( $this->label ) || is_null( $this->id ) ) { + + $this->trigger_registration_error(); return; @@ -87,23 +98,13 @@ public function register( $args = array() ) { } - public function parse_arguments( $args ) { - - $defaults = array( - 'label' => null, - 'id' => null, - 'post_type' => 'post', - 'priority' => 'low', - 'context' => 'side', - ); - - $args = wp_parse_args( $args, $defaults ); + public function trigger_registration_error() { - $args = array_intersect_key( $args, $defaults ); + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - foreach ( $args as $k => $v ) { + $error_message = $this->get_register_required_field_error_message(); - $this->$k = $v; + trigger_error( $error_message ); } From f08953f74f9656d9b07a9b1ba505eb231ef4f9de Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 11:52:32 -0400 Subject: [PATCH 17/29] Update test for register() call. --- tests/test-multi-post-thumbnails.php | 102 +++++++++++++-------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 8e731ae..0cc7ab8 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -45,72 +45,70 @@ public function assertError( $errstr, $errno = E_USER_NOTICE ) { } + // function test_register + function provider_test_register() { + /** + * Arguments for register() test: + * - $register_args - passed in to register() call + * - $expected_func_calls - array of functions we expect to be called + */ return array( - - array( true, true, true, 1, 0, 1, true ), - array( true, true, false, 1, 0, 1, true ), - - array( false, true, false, 1, 1, 1, true ), - - - array( false, false, false, 0, 0, 0, false, null, null, null ) - + /** + * All required args are specified + */ + array( + array( + 'id' => 'thumbnail-id', + 'label' => 'Thumbnail Label' + ), + array( + 'add_theme_support', + 'attach_hooks', + ) + ), + /** + * Missing required "id" arg + */ + array( + array( + 'label' => 'Thumbnail Label' + ), + array( + 'trigger_registration_error', + ) + ), + /** + * Missing required "label" arg + */ + array( + array( + 'id' => 'thumbnail-id' + ), + array( + 'trigger_registration_error', + ) + ) ); } - /** - * @covers MultiPostThumbnails::register - * @dataProvider provider_test_register - */ - function test_register( $current_theme_supports, $add_theme_support, $version_compare, $current_theme_supports_expects, $add_theme_support_expects, $version_compare_expects, $assertFilters, $label = 'foo', $id = 'bar', $post_type = 'post' ) { + function test_register( $register_args, $expected_func_calls ) { $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'version_compare', 'current_theme_supports', 'add_theme_support' ) ) - ->getMock(); - - $mpt->expects( $this->exactly( $current_theme_supports_expects ) ) - ->method( 'current_theme_supports' ) - ->will( $this->returnValue( $current_theme_supports ) ); - - $mpt->expects( $this->exactly( $add_theme_support_expects ) ) - ->method( 'add_theme_support' ) - ->will( $this->returnValue( $add_theme_support ) ); + ->disableOriginalConstructor() + ->setMethods( $expected_func_calls ) + ->getMock(); - $mpt->expects( $this->exactly( $version_compare_expects ) ) - ->method( 'version_compare' ) - ->will( $this->returnValue( $version_compare ) ); - - $mpt->register( array( 'label' => $label, 'id' => $id ) ); - - if ( ! $id || ! $label ) { - - $expected_error_msg = $mpt->get_register_required_field_error_message(); - - $this->assertError( $expected_error_msg ); - - } - - if ( $assertFilters ) { - - - $this->assertEquals( has_action( 'add_meta_boxes', array( $mpt, 'add_metabox' ) ), 10 ); - if ( $version_compare ) { - $this->assertEquals( has_filter( 'attachment_fields_to_edit', array( $mpt, 'add_attachment_field' ) ), 20 ); - } - $this->assertEquals( has_filter( 'admin_enqueue_scripts', array( $mpt, 'enqueue_admin_scripts' ) ), 10 ); - $this->assertEquals( has_filter( 'admin_print_scripts-post.php', array( $mpt, 'admin_header_scripts' ) ), 10 ); - $this->assertEquals( has_filter( 'admin_print_scripts-post-new.php', array( $mpt, 'admin_header_scripts' ) ), 10 ); - $this->assertEquals( has_filter( 'wp_ajax_set-' . $post_type . '-' . $id . '-thumbnail', array( $mpt, 'set_thumbnail' ) ), 10 ); - $this->assertEquals( has_filter( 'delete_attachment', array( $mpt, 'action_delete_attachment' ) ), 10 ); - $this->assertEquals( has_filter( 'is_protected_meta', array( $mpt, 'filter_is_protected_meta' ) ), 20 ); + foreach ( $expected_func_calls as $expected_func ) { + $mpt->expects( $this->once() ) + ->method( $expected_func ); } + $mpt->register( $register_args ); } From fc506139c79d2ec595c6b3142e1aa9e4523e78ad Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 11:56:56 -0400 Subject: [PATCH 18/29] Add directory whitelist for code coverage scoping/performance. --- phpunit.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpunit.xml b/phpunit.xml index 44f0fdb..87025b7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -11,4 +11,9 @@ ./tests/ + + + . + + From 999d26b64e081489651f134a72702fb96d59a53b Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 12:07:42 -0400 Subject: [PATCH 19/29] =?UTF-8?q?Scope=20the=20register()=20test=E2=80=99s?= =?UTF-8?q?=20coverage.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test-multi-post-thumbnails.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 0cc7ab8..fd6ba94 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -45,8 +45,6 @@ public function assertError( $errstr, $errno = E_USER_NOTICE ) { } - // function test_register - function provider_test_register() { /** @@ -94,6 +92,9 @@ function provider_test_register() { } + /** + * @covers MultiPostThumbnails::register + */ function test_register( $register_args, $expected_func_calls ) { $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) From 4cd1be0e312da828a6d15841f65cdd5613853e9a Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 12:15:06 -0400 Subject: [PATCH 20/29] Fix dataProvider hookup for test_register(). --- tests/test-multi-post-thumbnails.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index fd6ba94..c833554 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -93,6 +93,7 @@ function provider_test_register() { } /** + * @dataProvider provider_test_register * @covers MultiPostThumbnails::register */ function test_register( $register_args, $expected_func_calls ) { From 5a1d3f1bf08e5784a779067ca139632d7406864f Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 12:43:38 -0400 Subject: [PATCH 21/29] Test trigger_registration_error() --- multi-post-thumbnails.php | 26 ++++++++++++++++++-------- tests/test-multi-post-thumbnails.php | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index c6ed86b..48e92fb 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -98,6 +98,24 @@ public function register( $args = array() ) { } + /** + * Generate an error string for missing required constructor arguments + * + * @codeCoverageIgnore + * + * @return string Error message for missing required fields + */ + public function get_register_required_field_error_message() { + + $error_format = __( "The 'label' and 'id' values of the 'args' parameter of '%s::%s()' are required", 'multiple-post-thumbnails' ); + + return sprintf( $error_format, __CLASS__, __FUNCTION__ ); + + } + + /** + * If we are in debug mode, trigger an error when required fields are missing during registration + */ public function trigger_registration_error() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { @@ -138,14 +156,6 @@ public function attach_hooks() { } - public function get_register_required_field_error_message() { - - $error_format = __( "The 'label' and 'id' values of the 'args' parameter of '%s::%s()' are required", 'multiple-post-thumbnails' ); - - return sprintf( $error_format, __CLASS__, __FUNCTION__ ); - - } - /** * get the meta key used to store a post's thumbnail * diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index c833554..5a7e4c7 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -114,6 +114,29 @@ function test_register( $register_args, $expected_func_calls ) { } + /** + * @covers MultiPostThumbnails::trigger_registration_error + */ + function test_trigger_registration_error() { + + $error_message_method = 'get_register_required_field_error_message'; + $error_message = 'Error'; + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( $error_message_method ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( $error_message_method ) + ->will( $this->returnValue( $error_message ) ); + + $mpt->trigger_registration_error(); + + $this->assertError( $error_message ); + + } + /** * @covers MultiPostThumbnails::get_meta_key */ From 6cd96e743fdb21b5fbf7ee80315e7b12fa569553 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 12:59:38 -0400 Subject: [PATCH 22/29] Just add the theme support in register(), add test for it. --- multi-post-thumbnails.php | 16 ++++------------ tests/test-multi-post-thumbnails.php | 23 ++++++++++++++++------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 48e92fb..48644ca 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -29,6 +29,8 @@ class MultiPostThumbnails { + const THEME_SUPPORT = 'post-thumbnails'; + public $label; public $id; protected $post_type; @@ -92,7 +94,8 @@ public function register( $args = array() ) { } - $this->add_theme_support(); + // Ensure that the current theme supports post-thumbnails since MPT relies on it + add_theme_support( self::THEME_SUPPORT ); $this->attach_hooks(); @@ -128,17 +131,6 @@ public function trigger_registration_error() { } - public function add_theme_support() { - - // add theme support if not already added - if ( ! current_theme_supports( 'post-thumbnails' ) ) { - - add_theme_support( 'post-thumbnails' ); - - } - - } - public function attach_hooks() { global $wp_version; diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 5a7e4c7..8820d8e 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -49,8 +49,9 @@ function provider_test_register() { /** * Arguments for register() test: - * - $register_args - passed in to register() call - * - $expected_func_calls - array of functions we expect to be called + * - array $register_args - passed in to register() call + * - array $expected_func_calls - functions we expect to be called + * - bool $theme_has_thumbnail_support - whether or not post-thumbnails support has been added */ return array( /** @@ -62,9 +63,9 @@ function provider_test_register() { 'label' => 'Thumbnail Label' ), array( - 'add_theme_support', 'attach_hooks', - ) + ), + true ), /** * Missing required "id" arg @@ -75,7 +76,8 @@ function provider_test_register() { ), array( 'trigger_registration_error', - ) + ), + false ), /** * Missing required "label" arg @@ -86,7 +88,8 @@ function provider_test_register() { ), array( 'trigger_registration_error', - ) + ), + false ) ); @@ -96,7 +99,11 @@ function provider_test_register() { * @dataProvider provider_test_register * @covers MultiPostThumbnails::register */ - function test_register( $register_args, $expected_func_calls ) { + function test_register( $register_args, $expected_func_calls, $theme_has_thumbnail_support ) { + + // clean up side effects from other data sets + // @TODO determine where to put this logic, or if it's even necessary + remove_theme_support( MultiPostThumbnails::THEME_SUPPORT ); $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) ->disableOriginalConstructor() @@ -112,6 +119,8 @@ function test_register( $register_args, $expected_func_calls ) { $mpt->register( $register_args ); + $this->assertEquals( $theme_has_thumbnail_support, current_theme_supports( MultiPostThumbnails::THEME_SUPPORT ) ); + } /** From 6962f66bfb0526b40e0574a01f8cb6799bf3732e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 13:25:46 -0400 Subject: [PATCH 23/29] Code formatting in attach_hooks(). --- multi-post-thumbnails.php | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 48644ca..0b458f0 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -131,20 +131,29 @@ public function trigger_registration_error() { } + /** + * Attach all necessary WP hooks to this instance + * + * @global string $wp_version + */ public function attach_hooks() { global $wp_version; - add_action('add_meta_boxes', array($this, 'add_metabox')); + // hook in to the attachment form for versions of WP before the media modal was reworked if ( version_compare( $wp_version, '3.5', '<' ) ) { + add_filter('attachment_fields_to_edit', array($this, 'add_attachment_field'), 20, 2); + } - add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts')); - add_action('admin_print_scripts-post.php', array($this, 'admin_header_scripts')); - add_action('admin_print_scripts-post-new.php', array($this, 'admin_header_scripts')); - add_action("wp_ajax_set-{$this->post_type}-{$this->id}-thumbnail", array($this, 'set_thumbnail')); - add_action('delete_attachment', array($this, 'action_delete_attachment')); - add_filter('is_protected_meta', array($this, 'filter_is_protected_meta'), 20, 2); + + add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); + add_action( 'admin_print_scripts-post.php', array( $this, 'admin_header_scripts' ) ); + add_action( 'admin_print_scripts-post-new.php', array( $this, 'admin_header_scripts' ) ); + add_action( "wp_ajax_set-{$this->post_type}-{$this->id}-thumbnail", array( $this, 'set_thumbnail' ) ); + add_action( 'delete_attachment', array( $this, 'action_delete_attachment' ) ); + add_filter( 'is_protected_meta', array( $this, 'filter_is_protected_meta' ), 20, 2 ); } From 07f244e148d8585c300c0ae2780c06b8bad83491 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Sun, 14 Sep 2014 13:26:05 -0400 Subject: [PATCH 24/29] Test attach_hooks(). --- tests/test-multi-post-thumbnails.php | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 8820d8e..6a00cff 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -146,6 +146,49 @@ function test_trigger_registration_error() { } + /** + * @covers MultiPostThumbnails::attach_hooks + */ + function test_attach_hooks_wp_35() { + + $GLOBALS['wp_version'] = '3.5'; + + $mpt = new MultiPostThumbnails( array( + 'label' => 'Foo', + 'id' => 'foo', + 'post_type' => 'post' + ) ); + + $this->assertEquals( 10, has_action( 'add_meta_boxes', array( $mpt, 'add_metabox' ) ) ); + $this->assertEquals( 10, has_action( 'admin_print_scripts-post.php', array( $mpt, 'admin_header_scripts' ) ) ); + $this->assertEquals( 10, has_action( 'admin_print_scripts-post-new.php', array( $mpt, 'admin_header_scripts' ) ) ); + $this->assertEquals( 10, has_action( 'wp_ajax_set-post-foo-thumbnail', array( $mpt, 'set_thumbnail' ) ) ); + $this->assertEquals( 10, has_action( 'delete_attachment', array( $mpt, 'action_delete_attachment' ) ) ); + $this->assertEquals( 20, has_filter( 'is_protected_meta', array( $mpt, 'filter_is_protected_meta' ) ) ); + + // WP 3.5 and above shouldn't get the attachment_fields_to_edit filter + $this->assertFalse( has_filter( 'attachment_fields_to_edit', array( $mpt, 'add_attachment_field' ) ) ); + + } + + /** + * @covers MultiPostThumbnails::attach_hooks + */ + function test_attach_hooks_pre_wp_35() { + + $GLOBALS['wp_version'] = '3.4.2'; + + $mpt = new MultiPostThumbnails( array( + 'label' => 'Foo', + 'id' => 'foo', + 'post_type' => 'post' + ) ); + + // WP 3.4.x and below should get the attachment_fields_to_edit filter + $this->assertEquals( 20, has_filter( 'attachment_fields_to_edit', array( $mpt, 'add_attachment_field' ) ) ); + + } + /** * @covers MultiPostThumbnails::get_meta_key */ From 6d3f27021f5137e6dc811a63fb824a029fa4ffdc Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Mon, 15 Sep 2014 12:13:45 +0000 Subject: [PATCH 25/29] add test for test_thumbnail_meta_box --- tests/test-multi-post-thumbnails.php | 31 ++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 6a00cff..6a78e66 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -224,29 +224,34 @@ function test_add_metabox() { */ function test_thumbnail_meta_box() { - $post_id = 123; - $GLOBALS['post'] = (object) array( 'ID' => $post_id ); + $id = 'bar'; + $thumbnail_id = 'barfoo'; + $post = $this->factory->post->create_and_get(); + $GLOBALS['post'] = $post; $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) ->disableOriginalConstructor() - ->setMethods( array( 'post_thumbnail_html', 'get_post_meta', 'get_meta_key' ) ) + ->setMethods( array( 'get_meta_key' ) ) ->getMock(); + // set instance variables + $mpt->register( array( 'label' => 'foo', 'id' => $id ) ); + $mpt->expects( $this->once() ) ->method( 'get_meta_key' ) - ->will( $this->returnValue( 'metaKey' ) ); + ->will( $this->returnvalue( 'fozbar' ) ); + update_post_meta( $post->ID, 'fozbar', $thumbnail_id ); - $mpt->expects( $this->once() ) - ->method( 'get_post_meta' ) - ->with( $this->equalTo( $post_id ), $this->equalTo( 'metaKey' ), true ) - ->will( $this->returnValue( 'thumbnailid' ) ); - - $mpt->expects( $this->once() ) - ->method( 'post_thumbnail_html' ); - + ob_start(); $mpt->thumbnail_meta_box(); - + $output = ob_get_clean(); + $document = new DOMDocument; + $document->preserveWhiteSpace = false; + $document->loadHTML( $output ); + $xpath = new DOMXPath ( $document ); + $anchor_tag = $xpath->query( sprintf( "//a[@id='set-%s-%s-thumbnail' and @data-thumbnail_id='%s']", $post->post_type, $id, $thumbnail_id ) ); + $this->assertEquals( 1, $anchor_tag->length, 'MultiPostThumbnails::thumbnail_meta_box is not outputting HTML as expected' ); } From 004e340e0922ed305f9b039bbde2b4d4a01e9fa4 Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Mon, 15 Sep 2014 12:23:51 +0000 Subject: [PATCH 26/29] keep test in scope --- tests/test-multi-post-thumbnails.php | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index 6a78e66..f25027e 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -224,34 +224,26 @@ function test_add_metabox() { */ function test_thumbnail_meta_box() { - $id = 'bar'; $thumbnail_id = 'barfoo'; + $meta_key = 'fozbar'; $post = $this->factory->post->create_and_get(); $GLOBALS['post'] = $post; + update_post_meta( $post->ID, $meta_key, $thumbnail_id ); $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) ->disableOriginalConstructor() - ->setMethods( array( 'get_meta_key' ) ) + ->setMethods( array( 'get_meta_key', 'post_thumbnail_html' ) ) ->getMock(); - // set instance variables - $mpt->register( array( 'label' => 'foo', 'id' => $id ) ); - $mpt->expects( $this->once() ) ->method( 'get_meta_key' ) - ->will( $this->returnvalue( 'fozbar' ) ); + ->will( $this->returnvalue( $meta_key ) ); - update_post_meta( $post->ID, 'fozbar', $thumbnail_id ); + $mpt->expects( $this->once() ) + ->method( 'post_thumbnail_html') + ->with ( $this->equalTo( $thumbnail_id ) ); - ob_start(); $mpt->thumbnail_meta_box(); - $output = ob_get_clean(); - $document = new DOMDocument; - $document->preserveWhiteSpace = false; - $document->loadHTML( $output ); - $xpath = new DOMXPath ( $document ); - $anchor_tag = $xpath->query( sprintf( "//a[@id='set-%s-%s-thumbnail' and @data-thumbnail_id='%s']", $post->post_type, $id, $thumbnail_id ) ); - $this->assertEquals( 1, $anchor_tag->length, 'MultiPostThumbnails::thumbnail_meta_box is not outputting HTML as expected' ); } From d7714ff37ce49c2b75876afb75a5c85c999dd3ec Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Mon, 15 Sep 2014 12:28:13 -0400 Subject: [PATCH 27/29] refactor class to use shell instance objects --- multi-post-thumbnails.php | 115 ++++++++++++++++++++------- tests/test-multi-post-thumbnails.php | 26 ++---- 2 files changed, 92 insertions(+), 49 deletions(-) diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 0b458f0..746ff20 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -38,10 +38,12 @@ class MultiPostThumbnails { protected $context; /** + * @param array $args + * * @codeCoverageIgnore */ - public function __construct($args = array()) { - $this->register($args); + public function __construct($args = array() ) { + $this->register( $args ); } /** @@ -62,13 +64,16 @@ public function __construct($args = array()) { * context - The admin metabox context. Defaults to 'side'. * * @param array|string $args See above description. + * @param bool is this a shell call or do we need to register hooks * @return void */ - public function register( $args = array() ) { + public function register( $args = array(), $shell = true ) { + + $shell = !$shell ? true : false; // parse arugments and set defaults $defaults = array( - 'label' => null, + 'label' => ! $shell ? null : 'placeholder', 'id' => null, 'post_type' => 'post', 'priority' => 'low', @@ -86,7 +91,7 @@ public function register( $args = array() ) { } // "label" and "id" are required - if ( is_null( $this->label ) || is_null( $this->id ) ) { + if ( is_null( $this->label ) || is_null( $this->id ) ) { $this->trigger_registration_error(); @@ -97,7 +102,10 @@ public function register( $args = array() ) { // Ensure that the current theme supports post-thumbnails since MPT relies on it add_theme_support( self::THEME_SUPPORT ); - $this->attach_hooks(); + if ( ! $shell ) { + + $this->attach_hooks(); + } } @@ -183,7 +191,7 @@ public function add_metabox() { public function thumbnail_meta_box() { global $post; - $thumbnail_id = get_post_meta($post->ID, $this->get_meta_key(), true); + $thumbnail_id = $this->get_thumbnail_id( $post->ID ); echo $this->post_thumbnail_html($thumbnail_id); } @@ -329,29 +337,36 @@ private function plugins_url($relative_path, $plugin_path) { * @return bool Whether post has an image attached. */ public static function has_post_thumbnail($post_type, $id, $post_id = null) { - if (null === $post_id) { - $post_id = get_the_ID(); - } + + $post_id = $post_id ?: get_the_ID(); if (!$post_id) { return false; } + $mpt = new MultiPostThumbnails( compact( 'post_type', 'id' ), false ); + $thumbnail_id = $mpt->get_thumbnail_id( $post_id ); - return get_post_meta($post_id, "{$post_type}_{$id}_thumbnail_id", true); + return $thumbnail_id; } /** - * Display Post Thumbnail. + * Display Post Thumbnail * - * @param string $post_type The post type. - * @param string $thumb_id The id used to register the thumbnail. - * @param string $post_id Optional. Post ID. - * @param int $size Optional. Image size. Defaults to 'post-thumbnail', which theme sets using set_post_thumbnail_size( $width, $height, $crop_flag );. + * @param $post_type The post type + * @param $thumb_id The id used to register the thumbnail + * @param null $post_id Optional. Post ID. + * @param string $size Optional. Image size. Defaults to 'post-thumbnail', which theme sets using set_post_thumbnail_size( $width, $height, $crop_flag );. * @param string|array $attr Optional. Query string or array of attributes. - * @param bool $link_to_original Optional. Wrap link to original image around thumbnail? + * @param bool $link_to_original Optional. Wrap link to original image around thumbnail? + * @return void */ - public static function the_post_thumbnail($post_type, $thumb_id, $post_id = null, $size = 'post-thumbnail', $attr = '', $link_to_original = false) { - echo self::get_the_post_thumbnail($post_type, $thumb_id, $post_id, $size, $attr, $link_to_original); + public static function the_post_thumbnail($post_type, $thumb_id, $post_id = NULL, $size = 'post-thumbnail', $attr = '' , $link_to_original = false) { + + $post_id = $post_id ?: get_the_ID(); + $mpt = new MultiPostThumbnails( compact( 'post_type', 'thumb_id' ), false ); + $mpt->get_post_thumbnail($post_id, $size, $attr, $link_to_original, true ); + unset( $mpt ); + } /** @@ -363,16 +378,38 @@ public static function the_post_thumbnail($post_type, $thumb_id, $post_id = null * @param string $size Optional. Image size. Defaults to 'thumbnail'. * @param bool $link_to_original Optional. Wrap link to original image around thumbnail? * @param string|array $attr Optional. Query string or array of attributes. - */ + * @return string + */ public static function get_the_post_thumbnail($post_type, $thumb_id, $post_id = NULL, $size = 'post-thumbnail', $attr = '' , $link_to_original = false) { - global $id; - $post_id = (NULL === $post_id) ? get_the_ID() : $post_id; - $post_thumbnail_id = self::get_post_thumbnail_id($post_type, $thumb_id, $post_id); - $size = apply_filters("{$post_type}_{$post_id}_thumbnail_size", $size); + + $post_id = $post_id ?: get_the_ID(); + $mpt = new MultiPostThumbnails( compact( 'post_type', 'thumb_id' ), false ); + $post_thumbnail = $mpt->get_post_thumbnail($post_id, $size, $attr, $link_to_original, false ); + unset( $mpt ); + return $post_thumbnail; + + } + + + /** + * Retrieve the post thumbnail method + * + * @param $post_id + * @param $size + * @param $attr + * @param $link_to_original + * @param bool + * + * @return mixed|void + */ + public function get_post_thumbnail( $post_id, $size, $attr, $link_to_original, $echo = false ){ + + $post_thumbnail_id = $this->get_thumbnail_id( $post_id ); + $size = apply_filters("{$this->post_type}_{$post_id}_thumbnail_size", $size); if ($post_thumbnail_id) { - do_action("begin_fetch_multi_{$post_type}_thumbnail_html", $post_id, $post_thumbnail_id, $size); // for "Just In Time" filtering of all of wp_get_attachment_image()'s filters + do_action("begin_fetch_multi_{$this->post_type}_thumbnail_html", $post_id, $post_thumbnail_id, $size); // for "Just In Time" filtering of all of wp_get_attachment_image()'s filters $html = wp_get_attachment_image( $post_thumbnail_id, $size, false, $attr ); - do_action("end_fetch_multi_{$post_type}_thumbnail_html", $post_id, $post_thumbnail_id, $size); + do_action("end_fetch_multi_{$this->post_type}_thumbnail_html", $post_id, $post_thumbnail_id, $size); } else { $html = ''; } @@ -381,7 +418,12 @@ public static function get_the_post_thumbnail($post_type, $thumb_id, $post_id = $html = sprintf('%s', wp_get_attachment_url($post_thumbnail_id), $html); } - return apply_filters("{$post_type}_{$thumb_id}_thumbnail_html", $html, $post_id, $post_thumbnail_id, $size, $attr); + $post_thumbnail = apply_filters("{$this->post_type}_{$this->id}_thumbnail_html", $html, $post_id, $post_thumbnail_id, $size, $attr); + if ( ! $echo ) { + return $post_thumbnail; + } + echo $post_thumbnail; + } /** @@ -393,7 +435,18 @@ public static function get_the_post_thumbnail($post_type, $thumb_id, $post_id = * @return int */ public static function get_post_thumbnail_id($post_type, $id, $post_id) { - return get_post_meta($post_id, "{$post_type}_{$id}_thumbnail_id", true); + + $mpt = new MultiPostThumbnails( compact( 'post_type', 'id' ), false ); + $thumbnail_id = $mpt->get_thumbnail_id( $post_id ); + unset( $mpt ); + return $thumbnail_id; + + } + + public function get_thumbnail_id( $post_id ){ + + return get_post_meta( $post_id, $this->get_meta_key(), true ); + } /** @@ -411,7 +464,9 @@ public static function get_post_thumbnail_url($post_type, $id, $post_id = 0, $si } - $post_thumbnail_id = self::get_post_thumbnail_id($post_type, $id, $post_id); + $mpt = new MultiPostThumbnails( compact( 'post_type', 'id' ), false ); + + $post_thumbnail_id = $mpt->get_thumbnail_id( $post_id ); if ($size) { if ($url = wp_get_attachment_image_src($post_thumbnail_id, $size)) { @@ -422,7 +477,7 @@ public static function get_post_thumbnail_url($post_type, $id, $post_id = 0, $si } else { $url = wp_get_attachment_url($post_thumbnail_id); } - + unset( $mpt ); return $url; } diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index f25027e..7bad8e3 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -250,36 +250,24 @@ function test_thumbnail_meta_box() { /** * @covers MultiPostThumbnails::add_attachment_field */ - function test_add_attachment_field_none() { + function test_add_attachment_field_no_post_in_superglobal() { - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'wp_parse_args', 'wp_create_nonce', 'get_post' ) ) - ->getMock(); - - $mpt->expects( $this->never() ) - ->method( 'wp_parse_args' ); - - $mpt->expects( $this->never() ) - ->method( 'wp_create_nonce' ); + $mpt = new MultiPostThumbnails(); + $actual = $mpt->add_attachment_field('foo', 'bar'); + $this->assertEquals( 'foo', $actual ); - $mpt->expects( $this->never() ) - ->method( 'get_post' ); + } - $actual = $mpt->add_attachment_field( 'foo', 'bar' ); - $expected = 'foo'; - $this->assertEquals( $expected, $actual ); - } - /** * @covers MultiPostThumbnails::add_attachment_field */ function test_add_attachment_field_get_calling_post_id_null() { - $_GET['post_id'] = 123; + $post = $this->factory->post->create_and_get(); + $_GET['post_id'] = $post->ID; $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) ->disableOriginalConstructor() From cacf6814eb622380a27a43271646ff17bd3cc92d Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Tue, 16 Sep 2014 14:02:15 -0400 Subject: [PATCH 28/29] refactor class, update tests --- multi-post-thumbnails.php | 94 ++- tests/Voce_WP_UnitTestCase.php | 46 ++ tests/bootstrap.php | 12 +- tests/pluggable.php | 11 + tests/test-multi-post-thumbnails.php | 900 +++++++++++++++------------ 5 files changed, 613 insertions(+), 450 deletions(-) create mode 100644 tests/Voce_WP_UnitTestCase.php create mode 100644 tests/pluggable.php diff --git a/multi-post-thumbnails.php b/multi-post-thumbnails.php index 746ff20..12e1237 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -60,7 +60,7 @@ public function __construct($args = array() ) { * post_type - The post type to register this thumbnail for. Defaults to post. * * priority - The admin metabox priority. Defaults to 'low'. - * + * * context - The admin metabox context. Defaults to 'side'. * * @param array|string $args See above description. @@ -68,7 +68,6 @@ public function __construct($args = array() ) { * @return void */ public function register( $args = array(), $shell = true ) { - $shell = !$shell ? true : false; // parse arugments and set defaults @@ -80,10 +79,11 @@ public function register( $args = array(), $shell = true ) { 'context' => 'side', ); + + $args = wp_parse_args( $args, $defaults ); $args = array_intersect_key( $args, $defaults ); - foreach ( $args as $k => $v ) { $this->$k = $v; @@ -167,8 +167,8 @@ public function attach_hooks() { /** * get the meta key used to store a post's thumbnail - * - * @return string + * + * @return string */ public function get_meta_key() { return "{$this->post_type}_{$this->id}_thumbnail_id"; @@ -232,7 +232,11 @@ public function add_attachment_field($form_fields, $post) { $form_fields["{$this->post_type}-{$this->id}-thumbnail"] = array( 'label' => $this->label, 'input' => 'html', - 'html' => $link); + 'html' => $link + ); + + + return $form_fields; } @@ -245,7 +249,7 @@ public function add_attachment_field($form_fields, $post) { */ public function enqueue_admin_scripts( $hook ) { global $wp_version; - + // only load on select pages if ( ! in_array( $hook, array( 'post-new.php', 'post.php', 'media-upload-popup' ) ) ) return; @@ -254,12 +258,13 @@ public function enqueue_admin_scripts( $hook ) { add_thickbox(); wp_enqueue_script( "mpt-featured-image", $this->plugins_url( 'js/multi-post-thumbnails-admin.js', __FILE__ ), array( 'jquery', 'media-upload' ) ); } else { // 3.5+ media modal + wp_enqueue_media(); wp_enqueue_script( "mpt-featured-image", $this->plugins_url( 'js/multi-post-thumbnails-admin.js', __FILE__ ), array( 'jquery', 'set-post-thumbnail' ) ); - wp_enqueue_script( "mpt-featured-image-modal", $this->plugins_url( 'js/media-modal.js', __FILE__ ), array( 'jquery', 'media-models' ) ); + wp_enqueue_script( "mpt-featured-image-modal", $this->plugins_url( 'js/media-modal.js', __FILE__ ), array( 'jquery', 'media-models' ) ); } } - + public function admin_header_scripts() { $post_id = get_the_ID(); echo ""; @@ -277,23 +282,23 @@ public function action_delete_attachment($post_id) { $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = '%s' AND meta_value = %d", $this->get_meta_key(), $post_id )); } - + /** * make the meta for storing thumbnails protected so it doesn't show in the Custom Fields metabox - * + * * @param boolean $protected Passed in from filter * @param type $meta_key Passed in from filter - * @return boolean + * @return boolean */ public function filter_is_protected_meta($protected, $meta_key) { if (apply_filters('mpt_unprotect_meta', false)) { return $protected; } - + if ($meta_key == $this->get_meta_key()) { $protected = true; } - + return $protected; } @@ -334,7 +339,7 @@ private function plugins_url($relative_path, $plugin_path) { * @param string $post_type The post type. * @param string $id The id used to register the thumbnail. * @param string $post_id Optional. Post ID. - * @return bool Whether post has an image attached. + * @return bool|string Whether post has an image attached, if it does, the thumbnail id */ public static function has_post_thumbnail($post_type, $id, $post_id = null) { @@ -360,10 +365,10 @@ public static function has_post_thumbnail($post_type, $id, $post_id = null) { * @param bool $link_to_original Optional. Wrap link to original image around thumbnail? * @return void */ - public static function the_post_thumbnail($post_type, $thumb_id, $post_id = NULL, $size = 'post-thumbnail', $attr = '' , $link_to_original = false) { + public static function the_post_thumbnail($post_type, $id, $post_id = NULL, $size = 'post-thumbnail', $attr = '' , $link_to_original = false) { $post_id = $post_id ?: get_the_ID(); - $mpt = new MultiPostThumbnails( compact( 'post_type', 'thumb_id' ), false ); + $mpt = new MultiPostThumbnails( compact( 'post_type', 'id' ), false ); $mpt->get_post_thumbnail($post_id, $size, $attr, $link_to_original, true ); unset( $mpt ); @@ -377,13 +382,12 @@ public static function the_post_thumbnail($post_type, $thumb_id, $post_id = NULL * @param int $post_id Optional. Post ID. * @param string $size Optional. Image size. Defaults to 'thumbnail'. * @param bool $link_to_original Optional. Wrap link to original image around thumbnail? - * @param string|array $attr Optional. Query string or array of attributes. * @return string */ - public static function get_the_post_thumbnail($post_type, $thumb_id, $post_id = NULL, $size = 'post-thumbnail', $attr = '' , $link_to_original = false) { + public static function get_the_post_thumbnail($post_type, $id, $post_id = NULL, $size = 'post-thumbnail', $attr = '' , $link_to_original = false) { $post_id = $post_id ?: get_the_ID(); - $mpt = new MultiPostThumbnails( compact( 'post_type', 'thumb_id' ), false ); + $mpt = new MultiPostThumbnails( compact( 'post_type', 'id' ), false ); $post_thumbnail = $mpt->get_post_thumbnail($post_id, $size, $attr, $link_to_original, false ); unset( $mpt ); return $post_thumbnail; @@ -405,6 +409,7 @@ public static function get_the_post_thumbnail($post_type, $thumb_id, $post_id = public function get_post_thumbnail( $post_id, $size, $attr, $link_to_original, $echo = false ){ $post_thumbnail_id = $this->get_thumbnail_id( $post_id ); + $size = apply_filters("{$this->post_type}_{$post_id}_thumbnail_size", $size); if ($post_thumbnail_id) { do_action("begin_fetch_multi_{$this->post_type}_thumbnail_html", $post_id, $post_thumbnail_id, $size); // for "Just In Time" filtering of all of wp_get_attachment_image()'s filters @@ -419,6 +424,7 @@ public function get_post_thumbnail( $post_id, $size, $attr, $link_to_original, $ } $post_thumbnail = apply_filters("{$this->post_type}_{$this->id}_thumbnail_html", $html, $post_id, $post_thumbnail_id, $size, $attr); + if ( ! $echo ) { return $post_thumbnail; } @@ -443,6 +449,13 @@ public static function get_post_thumbnail_id($post_type, $id, $post_id) { } + /** + * Retrieve the thumbnail id + * + * @param $post_id + * + * @return mixed + */ public function get_thumbnail_id( $post_id ){ return get_post_meta( $post_id, $this->get_meta_key(), true ); @@ -491,10 +504,10 @@ public static function get_post_thumbnail_url($post_type, $id, $post_id = 0, $si */ protected function post_thumbnail_html($thumbnail_id = null) { global $content_width, $_wp_additional_image_sizes, $post_ID, $wp_version; - + $url_class = ""; $ajax_nonce = wp_create_nonce("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); - + if (version_compare($wp_version, '3.5', '<')) { // Use the old thickbox for versions prior to 3.5 $image_library_url = get_upload_iframe_src('image'); @@ -532,11 +545,11 @@ protected function post_thumbnail_html($thumbnail_id = null) { } $content_width = $old_content_width; } - + if (version_compare($wp_version, '3.5', '>=')) { $content .= sprintf('', $modal_js); } - + return apply_filters( sprintf( '%s_%s_admin_post_thumbnail_html', $this->post_type, $this->id ), $content, $post_ID, $thumbnail_id ); } @@ -550,30 +563,27 @@ public function set_thumbnail() { global $post_ID; // have to do this so get_upload_iframe_src() can grab it $post_ID = intval($_POST['post_id']); if ( !current_user_can('edit_post', $post_ID)) - return $this->mpt_die('-1'); + die('-1'); $thumbnail_id = intval($_POST['thumbnail_id']); - - $this->check_ajax_referer("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); - + check_ajax_referer("set_post_thumbnail-{$this->post_type}-{$this->id}-{$post_ID}"); if ($thumbnail_id == '-1') { delete_post_meta($post_ID, $this->get_meta_key()); - return $this->mpt_die($this->post_thumbnail_html(null)); + die($this->post_thumbnail_html(null)); } if ($thumbnail_id && get_post($thumbnail_id)) { $thumbnail_html = wp_get_attachment_image($thumbnail_id, 'thumbnail'); if (!empty($thumbnail_html)) { self::set_meta($post_ID, $this->post_type, $this->id, $thumbnail_id); - return $this->mpt_die($this->post_thumbnail_html($thumbnail_id)); + die($this->post_thumbnail_html($thumbnail_id)); } } - - return $this->mpt_die('0'); + die('0'); } - + /** * set thumbnail meta - * + * * @param int $post_ID * @param string $post_type * @param string $thumbnail_id ID used to register the thumbnail @@ -584,23 +594,11 @@ public static function set_meta($post_ID, $post_type, $thumbnail_id, $thumbnail_ return update_post_meta($post_ID, "{$post_type}_{$thumbnail_id}_thumbnail_id", $thumbnail_post_id); } - /** - * Helper method to assist mocking/testing of a global function (die, which is a keyword) - * - * @param $status - * - * @return mixed - * @codeCoverageIgnore - */ - public function mpt_die( $status ){ - if ( ! defined('WP_TEST_ENVIRONMENT') || WP_TEST_ENVIRONMENT === false ){ - die( $status ); - } - return $status; - } } if ( is_admin() ) load_plugin_textdomain( 'multiple-post-thumbnails', FALSE, basename( dirname( __FILE__ ) ) . '/languages/' ); } + + diff --git a/tests/Voce_WP_UnitTestCase.php b/tests/Voce_WP_UnitTestCase.php new file mode 100644 index 0000000..19e7c92 --- /dev/null +++ b/tests/Voce_WP_UnitTestCase.php @@ -0,0 +1,46 @@ +exit_called = false; + + if ( function_exists( 'unset_exit_overload' ) ) { + + unset_exit_overload(); + + } + + } + + function exit_overload() { + + $this->exit_called = true; + + } + + function exit_called() { + + return $this->exit_called; + + } + +} + diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 6a800da..2b9eee9 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,10 +2,16 @@ $_tests_dir = getenv('WP_TESTS_DIR'); -define( 'WP_TEST_ENVIRONMENT', true ); - if ( !$_tests_dir ) $_tests_dir = '/tmp/wordpress-tests-lib'; + +// Add this plugin to WordPress for activation so it can be tested. +$GLOBALS['wp_tests_options'] = array( + 'active_plugins' => array( 'multi-post-thumbnails/multi-post-thumbnails.php' ), +); + +require_once __DIR__ . '/pluggable.php'; + require_once $_tests_dir . '/includes/functions.php'; function _manually_load_plugin() { @@ -15,3 +21,5 @@ function _manually_load_plugin() { require $_tests_dir . '/includes/bootstrap.php'; + +require_once __DIR__ . '/Voce_WP_UnitTestCase.php'; \ No newline at end of file diff --git a/tests/pluggable.php b/tests/pluggable.php new file mode 100644 index 0000000..e9e2b7f --- /dev/null +++ b/tests/pluggable.php @@ -0,0 +1,11 @@ +errors = array(); - set_error_handler( array( $this, 'errorHandler' ) ); + + } + + /** + * If these tests are being run on Travis CI, verify that the version of + * WordPress installed is the version that we requested. + * + * @requires PHP 5.3 + */ + function test_wp_version() { + + if ( !getenv( 'TRAVIS' ) ) + $this->markTestSkipped( 'Test skipped since Travis CI was not detected.' ); + + $requested_version = getenv( 'WP_VERSION' ); + + // The "latest" version requires special handling. + if ( 'latest' === $requested_version ) { + + $file = file_get_contents( ABSPATH . WPINC . '/version.php' ); + preg_match( '#\$wp_version = \'([^\']+)\';#', $file, $matches ); + $requested_version = $matches[1]; + + } + + $this->assertEquals( get_bloginfo( 'version' ), $requested_version ); + + } + + /** + * Ensure that the plugin has been installed and activated. + */ + function test_plugin_activated() { + + $this->assertTrue( is_plugin_active( 'multi-post-thumbnails/multi-post-thumbnails.php' ) ); + } public function errorHandler( $errno, $errstr, $errfile, $errline, $errcontext ) { @@ -194,12 +229,15 @@ function test_attach_hooks_pre_wp_35() { */ function test_get_meta_key() { + // create an MPT instance, manually construct what the meta key should be for that instance $mpt = new MultiPostThumbnails( array( 'label' => 'foo', 'id' => 'bar', 'post_type' => 'post' ) ); - $actual = $mpt->get_meta_key(); $expected = 'post_bar_thumbnail_id'; + // get the meta key + $actual = $mpt->get_meta_key(); + $this->assertEquals( $expected, $actual ); } @@ -228,6 +266,8 @@ function test_thumbnail_meta_box() { $meta_key = 'fozbar'; $post = $this->factory->post->create_and_get(); $GLOBALS['post'] = $post; + + //manually set the value update_post_meta( $post->ID, $meta_key, $thumbnail_id ); $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) @@ -248,197 +288,134 @@ function test_thumbnail_meta_box() { } /** + * Feed the post_id in to the $_GET superglobal + * * @covers MultiPostThumbnails::add_attachment_field */ - function test_add_attachment_field_no_post_in_superglobal() { + function test_add_attachment_field_post_set_in_get() { - $mpt = new MultiPostThumbnails(); - $actual = $mpt->add_attachment_field('foo', 'bar'); - $this->assertEquals( 'foo', $actual ); - - } - - - - - /** - * @covers MultiPostThumbnails::add_attachment_field - */ - function test_add_attachment_field_get_calling_post_id_null() { - - $post = $this->factory->post->create_and_get(); - $_GET['post_id'] = $post->ID; + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $post_type = $post->post_type; - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'wp_parse_args', 'wp_create_nonce', 'get_post' ) ) - ->getMock(); - - $mpt->expects( $this->never() ) - ->method( 'wp_parse_args' ); - - $mpt->expects( $this->never() ) - ->method( 'wp_create_nonce' ); - - $mpt->expects( $this->once() ) - ->method( 'get_post' ) - ->will( $this->returnValue( null ) ); + $_GET['post_id'] = $post_id; + $id = 'foo'; - $actual = $mpt->add_attachment_field( 'foo', 'bar' ); - $expected = 'foo'; + $mpt = new MultiPostThumbnails( array( + 'label' => 'Bar', + 'id' => $id, + 'post_type' => $post_type + ) ); - $this->assertEquals( $expected, $actual ); + $field = $mpt->add_attachment_field( array(), $post ); + $this->arrayHasKey( sprintf( '%s-%s-thumbnail', $post_type, $id ), $field ); } /** + * Feed an array into $_POST to test async-upload + * * @covers MultiPostThumbnails::add_attachment_field */ - function test_add_attachment_field_get_unsupported_post_type() { + function test_add_attachment_field_post_superglobal_set() { - $_GET['post_id'] = 123; + $post_parent = $this->factory->post->create_and_get(); + $post = $this->factory->post->create_and_get( array('post_parent' => $post_parent->ID ) ); + $post_type = $post->post_type; + $_POST = array(1,2,3); + $id = 'foo'; - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'wp_parse_args', 'wp_create_nonce', 'get_post' ) ) - ->getMock(); - - $mpt->expects( $this->never() ) - ->method( 'wp_parse_args' ); - - $mpt->expects( $this->never() ) - ->method( 'wp_create_nonce' ); - - $mpt->expects( $this->once() ) - ->method( 'get_post' ) - ->will( $this->returnValue( (object) array( 'post_type' => 'not a known post type' ) ) ); - - $actual = $mpt->add_attachment_field( 'foo', 'bar' ); - $expected = 'foo'; - - $this->assertEquals( $expected, $actual ); + $mpt = new MultiPostThumbnails( array( + 'label' => 'Bar', + 'id' => $id, + 'post_type' => $post_type + ) ); + $field = $mpt->add_attachment_field( array(), $post ); + $this->arrayHasKey( sprintf( '%s-%s-thumbnail', $post_type, $id ), $field ); } /** * @covers MultiPostThumbnails::add_attachment_field */ - function test_add_attachment_field_get_unequal_context() { + function test_add_attachment_field_post_type_mismatch() { - $post = $this->factory->post->create_and_get(); - $post_id = $post->ID; + $id = 'foo'; + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; $_GET['post_id'] = $post_id; - $id = 123; - $post_type = 'post'; - - $mpt = new MultiPostThumbnails( array( 'id' => $id, 'label' => 'thelabel', 'post_type' => $post_type ) ); - - $add_attachment_field = $mpt->add_attachment_field( array(), $post ); - - $this->assertArrayHasKey( $post_type . '-' . $id . '-thumbnail', $add_attachment_field ); + $mpt = new MultiPostThumbnails( array( + 'label' => 'Bar', + 'id' => $id, + 'post_type' => 'notpost' + ) ); + $field = $mpt->add_attachment_field( array(), $post ); + $this->assertEquals( array(), $field ); } /** * @covers MultiPostThumbnails::add_attachment_field */ - function test_add_attachment_field_get() { - - $post = $this->factory->post->create_and_get(); - $post_id = $post->ID; - $_GET['post_id'] = $post_id; - $id = 123; - $post_type = 'post'; - - $mpt = new MultiPostThumbnails( array( 'id' => $id, 'label' => 'thelabel', 'post_type' => $post_type ) ); + function test_add_attachment_field_no_post_parent() { - $add_attachment_field = $mpt->add_attachment_field( array(), $post ); + $post = $this->factory->post->create_and_get(); + $post_type = $post->post_type; + $_POST = array(1,2,3); + $id = 'foo'; - $this->assertArrayHasKey( $post_type . '-' . $id . '-thumbnail', $add_attachment_field ); + $mpt = new MultiPostThumbnails( array( + 'label' => 'Bar', + 'id' => $id, + 'post_type' => $post_type + ) ); + $field = $mpt->add_attachment_field( array(), $post ); + $this->assertEquals( array(), $field ); } - /** - * @covers MultiPostThumbnails::add_attachment_field - */ - function test_add_attachment_field_post() { - - $post = $this->factory->post->create_and_get(); - $post_id = $post->ID; - $post2 = $this->factory->post->create_and_get( array( 'post_parent' => $post_id ) ); - $_POST = array( 1, 2, 3 ); - $id = 123; - $post_type = 'post'; - - $mpt = new MultiPostThumbnails( array( 'id' => $id, 'label' => 'thelabel', 'post_type' => $post_type ) ); - - $add_attachment_field = $mpt->add_attachment_field( array(), $post2 ); - - $this->assertArrayHasKey( $post_type . '-' . $id . '-thumbnail', $add_attachment_field ); - - } /** - * @covers MultiPostThumbnails::enqueue_admin_scripts + * Arguments for enqueue_admin_scripts() test: + * - string $wp_version - Version of WordPress + * - array $scripts_expected - scripts that are expected to be enqueued + * - array $scripts_not_expected - scripts NOT expected to be enqueued */ - function test_enqueue_admin_scripts_wp_version_34() { - - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'version_compare' ) ) - ->getMock(); - - $mpt->expects( $this->once() ) - ->method( 'version_compare' ) - ->will( $this->returnValue( true ) ); - - $mpt->enqueue_admin_scripts( 'post-new.php' ); + function provider_test_enqueue_admin_scripts(){ - $this->assertTrue( wp_script_is( 'thickbox' ) ); - $this->assertTrue( wp_script_is( 'mpt-featured-image' ) ); + return array( + /* WP version 3.4 and expected scripts */ + array( '3.4', 'post-new.php', array( 'thickbox', 'mpt-featured-image' ), array( 'mpt-featured-image-modal', 'media-editor' ) ), + /* WP version 4.0 and expected scripts */ + array( '4.0', 'post-new.php', array( 'mpt-featured-image-modal', 'media-editor', 'mpt-featured-image' ), array( 'thickbox' ) ), + ); } + /** + * @dataProvider provider_test_enqueue_admin_scripts * @covers MultiPostThumbnails::enqueue_admin_scripts */ - function test_enqueue_admin_scripts_wp_version_40() { - - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'version_compare' ) ) - ->getMock(); - - $mpt->expects( $this->once() ) - ->method( 'version_compare' ) - ->will( $this->returnValue( false ) ); - - $mpt->enqueue_admin_scripts( 'post-new.php' ); + function test_enqueue_admin_scripts( $version, $hook, $scripts_expected, $scripts_not_expected ) { - $this->assertTrue( wp_script_is( 'mpt-featured-image' ) ); - $this->assertTrue( wp_script_is( 'mpt-featured-image-modal' ) ); - $this->assertTrue( wp_script_is( 'media-editor' ) ); + $GLOBALS['wp_version'] = $version; - } + $mpt = new MultiPostThumbnails(); + $mpt->enqueue_admin_scripts( $hook ); + foreach( $scripts_expected as $script ) { + $this->assertTrue( wp_script_is( $script, 'enqueued' ) ); - /** - * @covers MultiPostThumbnails::enqueue_admin_scripts - */ - function test_enqueue_admin_scripts_not_in_hook_array() { - - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'version_compare' ) ) - ->getMock(); + } + foreach( $scripts_not_expected as $script ) { - $mpt->expects( $this->never() ) - ->method( 'version_compare' ); + $this->assertFalse( wp_script_is( $script, 'enqueued' ) ); - $mpt->enqueue_admin_scripts( 'NOTINARRAY' ); + } } @@ -448,13 +425,12 @@ function test_enqueue_admin_scripts_not_in_hook_array() { function test_admin_header_scripts() { $post = $this->factory->post->create_and_get(); - $post->ID = 10000; $GLOBALS['post'] = $post; $mpt = new MultiPostThumbnails; ob_start(); $mpt->admin_header_scripts(); $output = ob_get_clean(); - $this->assertEquals( '', $output ); + $this->assertEquals( sprintf( '', $post->ID ) , $output ); } @@ -477,11 +453,18 @@ function test_action_delete_attachment() { global $wpdb; + // insert an arbitrary attachment + $wpdb->query( $wpdb->prepare( "INSERT INTO $wpdb->postmeta ( meta_key, meta_value ) values ( '%s', %d )", $mpt->get_meta_key(), $post_id ) ); + // check that the attachment exists $result = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->postmeta WHERE meta_key = '%s' AND meta_value = %d", $mpt->get_meta_key(), $post_id ) ); $this->assertEquals( 1, count( $result ) ); + + //execute MultiPostThumbnails::action_delete_attachment $mpt->action_delete_attachment( $post_id ); + + // check that the attachment no longer exists $result = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->postmeta WHERE meta_key = '%s' AND meta_value = %d", $mpt->get_meta_key(), $post_id ) ); $this->assertEquals( 0, count( $result ) ); @@ -490,81 +473,58 @@ function test_action_delete_attachment() { /** * @covers MultiPostThumbnails::filter_is_protected_meta */ - function test_filter_is_protected_meta_filter_returns_true() { + function test_filter_is_protected_meta_meta_key_equals() { $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) ->disableOriginalConstructor() - ->setMethods( array( 'apply_filters' ) ) + ->setMethods( array( 'get_meta_key' ) ) ->getMock(); $mpt->expects( $this->once() ) - ->method( 'apply_filters' ) - ->with( $this->equalTo( 'mpt_unprotect_meta' ), $this->equalTo( false ) ) - ->will( $this->returnValue( true ) ); - - $expected = 'foo'; - $actual = $mpt->filter_is_protected_meta( $expected, 'bar' ); - - $this->assertEquals( $expected, $actual ); + ->method( 'get_meta_key' ) + ->will( $this->returnValue( 'meta_key' ) ); + $actual = $mpt->filter_is_protected_meta( 'foo', 'meta_key' ); + $this->assertTrue( $actual ); } /** * @covers MultiPostThumbnails::filter_is_protected_meta */ - function test_filter_is_protected_meta_filter_meta_key_equals() { - - $meta_key = 'bar'; + function test_filter_is_protected_meta_meta_key_unequal() { $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) ->disableOriginalConstructor() - ->setMethods( array( 'apply_filters', 'get_meta_key' ) ) + ->setMethods( array( 'get_meta_key' ) ) ->getMock(); - $mpt->expects( $this->once() ) - ->method( 'apply_filters' ) - ->with( $this->equalTo( 'mpt_unprotect_meta' ), $this->equalTo( false ) ) - ->will( $this->returnValue( false ) ); - $mpt->expects( $this->once() ) ->method( 'get_meta_key' ) - ->will( $this->returnValue( $meta_key ) ); + ->will( $this->returnValue( 'NOT_META_KEY' ) ); - $expected = 'foo'; - $actual = $mpt->filter_is_protected_meta( $expected, $meta_key ); - $this->assertTrue( $actual ); + // pass foo as the first argument, and expect it to be returned by MultiPostThumbnails::filter_is_protected_meta + $expected = 'foo'; + $actual = $mpt->filter_is_protected_meta( $expected, 'meta_key' ); + $this->assertEquals( $actual, $expected ); } /** * @covers MultiPostThumbnails::filter_is_protected_meta */ - function test_filter_is_protected_meta_filter_meta_key_not_equals() { - - $meta_key = 'bar'; - - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'apply_filters', 'get_meta_key' ) ) - ->getMock(); - - $mpt->expects( $this->once() ) - ->method( 'apply_filters' ) - ->with( $this->equalTo( 'mpt_unprotect_meta' ), $this->equalTo( false ) ) - ->will( $this->returnValue( false ) ); + function test_filter_is_protected_meta_filter() { - $mpt->expects( $this->once() ) - ->method( 'get_meta_key' ) - ->will( $this->returnValue( 'not meta key' ) ); + // add filter to return true + add_filter( 'mpt_unprotect_meta', '__return_true' ); + $mpt = new MultiPostThumbnails(); + // pass foo as the first argument, and expect it to be returned by MultiPostThumbnails::filter_is_protected_meta $expected = 'foo'; - $actual = $mpt->filter_is_protected_meta( $expected, $meta_key ); - - $this->assertEquals( $actual, $expected ); - + $actual = $mpt->filter_is_protected_meta( $expected, 'meta_key' ); + $this->assertEquals( $expected, $actual ); } @@ -575,9 +535,13 @@ function test_has_post_thumbnail() { $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); $id = 'bar'; + + //build the expected meta key and set a value to test $expected = 'foz'; - update_post_meta( $post->ID, 'post_' . $id . '_thumbnail_id', $expected ); + // set the meta + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $id, $expected); + $GLOBALS['post'] = $post; $actual = MultiPostThumbnails::has_post_thumbnail( 'post', $id ); @@ -591,399 +555,535 @@ function test_has_post_thumbnail() { */ function test_has_post_thumbnail_no_post_id() { + // if no post is set, it should return false $actual = MultiPostThumbnails::has_post_thumbnail( 'post', 'foz', false ); $this->assertFalse( $actual ); } /** - * @covers MultiPostThumbnails::get_the_post_thumbnail + * @covers MultiPostThumbnails::the_post_thumbnail */ - function test_get_the_post_thumbnail_set_meta() { + function test_the_post_thumbnail() { - $thumbnail_id = 'foobar'; + // test that MultiPostThumbnails::the_post_thumbnail echos the post thumbnail - $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); - $attachment_id = $this->factory->attachment->create_object( 'foo.jpg', $post->ID, array( + $filename = 'foo.jpg'; + $upload_array = wp_upload_dir(); + $upload_base_url = $upload_array['baseurl']; + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment' ) ); - MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); - $actual = MultiPostThumbnails::get_the_post_thumbnail( 'post', $thumbnail_id, $post->ID, 'post-thumbnail', '', true ); + $post_type = $post->post_type; + $id = 'foobar'; - $image_link = wp_get_attachment_image( $attachment_id, 'post-thumbnail', false, '' ); - $url = wp_get_attachment_url( $attachment_id ); - $expected = sprintf( '%s', $url, $image_link ); + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); - $this->assertEquals( $actual, $expected ); + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->getMock(); + + $mpt->register(array('post_type' => 'post', 'id' => $id), false ); + ob_start(); + MultiPostThumbnails::the_post_thumbnail( $post_type, $id, $post->ID); + $output = ob_get_clean(); + + $document = new DOMDocument; + $document->preserveWhiteSpace = false; + $document->loadHTML( $output ); + $xpath = new DOMXPath ( $document ); + $anchor_tag = $xpath->query( "//img[@src='" . $upload_base_url . '/' . $filename . "']" ); + $this->assertEquals( 1, $anchor_tag->length ); } /** * @covers MultiPostThumbnails::get_the_post_thumbnail */ - function test_get_the_post_thumbnail_unset_meta() { + function test_get_the_post_thumbnail() { - $thumbnail_id = 'foobar'; - $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); - $actual = MultiPostThumbnails::get_the_post_thumbnail( 'post', $thumbnail_id, $post->ID, 'post-thumbnail', '', true ); - $expected = null; - $this->assertEquals( $actual, $expected ); + // test that MultiPostThumbnails::get_the_post_thumbnail returns the post thumbnail - } + $filename = 'foo.jpg'; + $upload_directory_array = wp_upload_dir(); + $upload_directory = $upload_directory_array['baseurl']; - /** - * @covers MultiPostThumbnails::the_post_thumbnail - */ - function test_the_post_thumbnail() { + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); - $thumbnail_id = 'foobar'; - $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $post_type = $post->post_type; + $id = 'foobar'; + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); - $expected = MultiPostThumbnails::get_the_post_thumbnail( 'post', $thumbnail_id, $post->ID, 'post-thumbnail', '', true ); + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->getMock(); - ob_start(); - MultiPostThumbnails::the_post_thumbnail( 'post', $thumbnail_id, $post->ID, $post->ID, 'post-thumbnail', '', true ); - $actual = ob_get_clean(); + $mpt->register(array('post_type' => 'post', 'id' => $id), false ); - $this->assertEquals( $actual, $expected ); + $output = MultiPostThumbnails::get_the_post_thumbnail( $post_type, $id, $post->ID); + $document = new DOMDocument; + $document->preserveWhiteSpace = false; + $document->loadHTML( $output ); + $xpath = new DOMXPath ( $document ); + $anchor_tag = $xpath->query( "//img[@src='" . $upload_directory . '/' . $filename . "']" ); + $this->assertEquals( 1, $anchor_tag->length ); } /** - * @covers MultiPostThumbnails::get_post_thumbnail_id + * @covers MultiPostThumbnails::get_post_thumbnail */ + function test_get_post_thumbnail(){ - public function test_get_post_thumbnail_id(){ + // test that MultiPostThumbnails::get_post_thumbnail returns the post thumbnail - $post_type = 'page'; - $thumbnail_id = 'foo'; - $thumbnail_post_id = 'bar'; - $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); - MultiPostThumbnails::set_meta( $post_id, $post_type, $thumbnail_id, $thumbnail_post_id); + $filename = 'foo.jpg'; + $upload_directory_array = wp_upload_dir(); + $upload_directory = $upload_directory_array['baseurl']; - $actual = MultiPostThumbnails::get_post_thumbnail_id( $post_type, $thumbnail_id, $post_id ); + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + $id = 'foo'; + + $mpt = new MultiPostThumbnails( array( + 'label' => 'Foo', + 'id' => $id, + 'post_type' => 'post' + ) ); + + $post_type = $post->post_type; + + + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + + $actual = $mpt->get_post_thumbnail( $post->ID, 'post-thumbnail', '', false ); + $document = new DOMDocument; + $document->preserveWhiteSpace = false; + $document->loadHTML( $actual ); + $xpath = new DOMXPath ( $document ); + $anchor_tag = $xpath->query( "//img[@src='" . $upload_directory . '/' . $filename . "']" ); + $this->assertEquals( 1, $anchor_tag->length ); - $this->assertEquals( $thumbnail_post_id, $actual ); } /** - * @covers MultiPostThumbnails::get_post_thumbnail_url + * @covers MultiPostThumbnails::get_post_thumbnail */ - public function test_get_post_thumbnail_url() { + function test_get_post_thumbnail_echo_link_to_original(){ - $post = $this->factory->post->create_and_get(); - $GLOBALS['post'] = $post; - $thumbnail_id = 'foobar'; - $file_name = 'foo.jpg'; + // test that MultiPostThumbnails::get_post_thumbnail echos the post thumbnail + + $filename = 'foo.jpg'; + $upload_directory_array = wp_upload_dir(); + $upload_directory = $upload_directory_array['baseurl']; - $attachment_id = $this->factory->attachment->create_object( $file_name, $post->ID, array( + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment' ) ); + $id = 'foo'; - MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); - - $upload_dir_raw = wp_upload_dir(); - $upload_url = str_replace( $upload_dir_raw['subdir'], '', $upload_dir_raw['url'] ); //strip out the month/date from URL + $mpt = new MultiPostThumbnails( array( + 'label' => 'Foo', + 'id' => $id, + 'post_type' => 'post' + ) ); - $expected = $upload_url . '/' . $file_name; + $post_type = $post->post_type; - $actual = MultiPostThumbnails::get_post_thumbnail_url( 'post', $thumbnail_id ); + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); - $this->assertEquals( $actual, $expected ); + ob_start(); + $mpt->get_post_thumbnail( $post->ID, 'post-thumbnail', '', true, true ); + $output = ob_get_clean(); + $document = new DOMDocument; + $document->preserveWhiteSpace = false; + $document->loadHTML( $output ); + $xpath = new DOMXPath ( $document ); + $anchor_tag = $xpath->query( "//a[@href='" . $upload_directory . '/' . $filename . "']" ); + $this->assertEquals( 1, $anchor_tag->length ); } /** - * @covers MultiPostThumbnails::get_post_thumbnail_url + * @covers MultiPostThumbnails::get_post_thumbnail */ - public function test_get_post_thumbnail_url_size() { + function test_get_post_thumbnail_no_post_thumbnail(){ - $post = $this->factory->post->create_and_get(); - $GLOBALS['post'] = $post; - $thumbnail_id = 'foobar'; - $file_name = 'foo.jpg'; + // test that MultiPostThumbnails::get_post_thumbnail returns an empty string when no post thumbnail exists - $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); - $attachment_id = $this->factory->attachment->create_object( $file_name, $post->ID, array( - 'post_mime_type' => 'image/jpeg', - 'post_type' => 'attachment' + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $id = 'foo'; + + $mpt = new MultiPostThumbnails( array( + 'label' => 'Foo', + 'id' => $id, + 'post_type' => 'post' ) ); - MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); + ob_start(); + $mpt->get_post_thumbnail( $post->ID, 'post-thumbnail', '', true, true ); + $output = ob_get_clean(); + $this->assertEquals('', $output); + + } + + /** + * @covers MultiPostThumbnails::get_post_thumbnail_id + */ - $upload_dir_raw = wp_upload_dir(); - $upload_url = str_replace( $upload_dir_raw['subdir'], '', $upload_dir_raw['url'] ); //strip out the month/date from URL + function test_get_post_thumbnail_id(){ - $expected = $upload_url . '/' . $file_name; + // test that the proper URL is returned when calling MultiPostThumbnails::get_post_thumbnail_url - $actual = MultiPostThumbnails::get_post_thumbnail_url( 'post', $thumbnail_id, $post->ID, 'size' ); + $filename = 'foo.jpg'; + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); - $this->assertEquals( $actual, $expected ); + $post_type = $post->post_type; + $id = 'foobar'; + + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + $thumbnail_id = MultiPostThumbnails::get_post_thumbnail_id( $post_type, $id, $post->ID ); + $this->assertEquals( $attachment_id, $thumbnail_id ); } /** * @covers MultiPostThumbnails::get_post_thumbnail_url */ - public function test_get_post_thumbnail_url_size_no_attachment() { + function test_get_post_thumbnail_url(){ - $post = $this->factory->post->create_and_get(); + // test that the proper URL is returned when calling MultiPostThumbnails::get_post_thumbnail_url + + $filename = 'foo.jpg'; + $upload_array = wp_upload_dir(); + $upload_base_url = $upload_array['baseurl']; + + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); $GLOBALS['post'] = $post; - $thumbnail_id = 'foobar'; + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); - $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); - $attachment_id = null; - MultiPostThumbnails::set_meta( $post->ID, 'post', $thumbnail_id, $attachment_id ); + $post_type = $post->post_type; + $id = 'foobar'; - $upload_dir_raw = wp_upload_dir(); - $upload_url = str_replace( $upload_dir_raw['subdir'], '', $upload_dir_raw['url'] ); //strip out the month/date from URL + $expected = $upload_base_url . '/' . $filename; - $expected = ''; + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + $actual = MultiPostThumbnails::get_post_thumbnail_url( $post_type, $id ); - $actual = MultiPostThumbnails::get_post_thumbnail_url( 'post', $thumbnail_id, $post->ID, 'size' ); - $this->assertEquals( $actual, $expected ); + $this->assertEquals( $expected, $actual ); } + /** - * @covers MultiPostThumbnails::set_thumbnail + * @covers MultiPostThumbnails::get_post_thumbnail_url */ - public function test_set_thumbnail_current_user_cannot() { - - $post_id = $this->factory->post->create(); - $_POST['post_id'] = $post_id; - - $user_id = $this->factory->user->create( array( 'role' => 'subscriber' ) ); - wp_set_current_user( $user_id ); + function test_get_post_thumbnail_url_with_size(){ - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'mpt_die', 'check_ajax_referer', 'set_meta', 'post_thumbnail_html', 'get_meta_key' ) ) - ->getMock(); + // test that the proper URL is returned when calling MultiPostThumbnails::get_post_thumbnail_url - $mpt->expects( $this->once() ) - ->method( 'mpt_die' ) - ->with( $this->equalTo( '-1' ) ); + $filename = 'foo.jpg'; + $upload_array = wp_upload_dir(); + $upload_base_url = $upload_array['baseurl']; - $mpt->expects( $this->never() ) - ->method( 'check_ajax_referer' ); + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $GLOBALS['post'] = $post; + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); - $mpt->expects( $this->never() ) - ->method( 'set_meta' ); - $mpt->expects( $this->never() ) - ->method( 'get_meta_key' ); + $post_type = $post->post_type; + $id = 'foobar'; - $mpt->expects( $this->never() ) - ->method( 'post_thumbnail_html' ); + $expected = $upload_base_url . '/' . $filename; + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + $actual = MultiPostThumbnails::get_post_thumbnail_url( $post_type, $id, 0, 'post-thumbnail' ); - $mpt->set_thumbnail(); + $this->assertEquals( $expected, $actual ); } + /** - * @covers MultiPostThumbnails::set_thumbnail + * @covers MultiPostThumbnails::get_post_thumbnail_url */ - public function test_set_thumbnail_current_user_can_thumbnail_negative_1() { + function test_get_post_thumbnail_url_with_size_set_post_set_to_null(){ - $post_id = $this->factory->post->create(); - $_POST['post_id'] = $post_id; - $_POST['thumbnail_id'] = '-1'; - $id = null; - $post_type = null; + $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); + $GLOBALS['post'] = null; + $attachment_id = $this->factory->attachment->create_object( 'foo.jpg', $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); - $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); - wp_set_current_user( $user_id ); + $post_type = $post->post_type; + $id = 'foobar'; + $expected = ''; - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'check_ajax_referer', 'set_meta', 'get_meta_key' ) ) - ->getMock(); + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + $actual = MultiPostThumbnails::get_post_thumbnail_url( $post_type, $id, 0, 'post-thumbnail' ); + $this->assertEquals( $expected, $actual ); - $mpt->expects( $this->once() ) - ->method( 'get_meta_key' ); + } - $mpt->expects( $this->once() ) - ->method( 'check_ajax_referer' ); - $mpt->expects( $this->never() ) - ->method( 'set_meta' ); + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + function test_set_thumbnail_user_cannot(){ + // test that the post meta does not get changed + + $user_id = $this->factory->user->create( array( 'role' => 'subscriber' ) ); + wp_set_current_user( $user_id ); + $value_to_set_meta_before_set_thumbnail = 'barfoo'; + $id = 'foobar'; + $post = $this->factory->post->create_and_get(); + $_POST['post_id'] = $post->ID; - $result = $mpt->set_thumbnail(); + $mpt = new MultiPostThumbnails(); + $mpt->register( compact('post_type', 'id' ), false ); + // add a dummy value to test against after running MultiPostThumbnails::set_thumbnail + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $id, $value_to_set_meta_before_set_thumbnail ); - $document = new DOMDocument; - $document->preserveWhiteSpace = false; - $document->loadHTML( $result ); - $xpath = new DOMXPath ( $document ); - $anchor_tag = $xpath->query( "//a[@id='set-" . $post_type . "-" . $id . "-thumbnail']" ); - $this->assertEquals( 1, $anchor_tag->length ); + $mpt->set_thumbnail(); + + $actual = $mpt->get_thumbnail_id ( $post->ID ); + + // make sure that the value does not change by MultiPostThumbnails::set_thumbnail + $this->assertEquals( $actual, $value_to_set_meta_before_set_thumbnail ); + $this->assertTrue( $this->exit_called ); } + /** * @covers MultiPostThumbnails::set_thumbnail */ - public function test_set_thumbnail_current_user_can_thumbnail_not_a_post() { + function test_set_thumbnail_user_can_thumbnail_id_negative_1(){ - $post_id = $this->factory->post->create(); - $_POST['post_id'] = $post_id; - $_POST['thumbnail_id'] = 'notapostid'; + // test that the post meta gets deleted $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); - wp_set_current_user( $user_id ); - - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'mpt_die', 'check_ajax_referer', 'set_meta', 'post_thumbnail_html', 'get_meta_key' ) ) - ->getMock(); - - $mpt->expects( $this->once() ) - ->method( 'mpt_die' ) - ->with( $this->equalTo( '0' ) ); + $value_to_set_meta_before_set_thumbnail = 'barfoo'; + $post = $this->factory->post->create_and_get(); + $post_type = $post->post_type; + $id = 'foobar'; + $_POST['post_id'] = $post->ID; + $_POST['thumbnail_id'] = '-1'; - $mpt->expects( $this->once() ) - ->method( 'check_ajax_referer' ); + wp_set_current_user( $user_id ); - $mpt->expects( $this->never() ) - ->method( 'set_meta' ); + // add a dummy value to test against after running MultiPostThumbnails::set_thumbnail + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $id, $value_to_set_meta_before_set_thumbnail ); - $mpt->expects( $this->never() ) - ->method( 'get_meta_key' ); + $mpt = new MultiPostThumbnails(); + $mpt->register( compact('post_type', 'id' ), false ); - $mpt->expects( $this->never() ) - ->method( 'post_thumbnail_html' ); + $mpt->set_thumbnail(); + $actual = $mpt->get_thumbnail_id ( $post->ID ); - $mpt->set_thumbnail(); + // make sure that the value does not persist as it should be deleted by MultiPostThumbnails::set_thumbnail + $this->assertNotEquals( $actual, $value_to_set_meta_before_set_thumbnail ); + $this->assertTrue( $this->exit_called ); } /** * @covers MultiPostThumbnails::set_thumbnail */ - public function test_set_thumbnail_is_a_post() { + function test_set_thumbnail_user_can(){ - $post_type = 'post'; - $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); - $attachment_id = $this->factory->attachment->create_object( 'foo.jpg', $post_id, array( + // if the user can set the thumbnail, the meta value should change + + $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); + $value_to_set_meta_before_set_thumbnail = 'foobar'; + $post = $this->factory->post->create_and_get(); + $filename = 'foo.jpg'; + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment' ) ); - - $id = 'barfoo'; - $_POST['post_id'] = $post_id; + $post_type = $post->post_type; + $id = 'foobar'; + $_POST['post_id'] = $post->ID; $_POST['thumbnail_id'] = $attachment_id; + wp_set_current_user( $user_id ); - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'check_ajax_referer', 'get_meta_key' ) ) - ->getMock(); + // add a dummy value to test against after running MultiPostThumbnails::set_thumbnail + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $id, $value_to_set_meta_before_set_thumbnail ); - $mpt->register( array( 'label' => 'foobar', 'id' => $id ) ); + $mpt = new MultiPostThumbnails(); + $mpt->register( compact('post_type', 'id' ), false ); + $mpt->set_thumbnail(); + $actual = $mpt->get_thumbnail_id ( $post->ID ); + // make sure that the value changes as it should be changed by MultiPostThumbnails::set_thumbnail + $this->assertNotEquals( $value_to_set_meta_before_set_thumbnail, $actual ); - $mpt->expects( $this->once() ) - ->method( 'check_ajax_referer' ); + $this->assertTrue( $this->exit_called ); - $mpt->expects( $this->never() ) - ->method( 'get_meta_key' ); + } + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + function test_set_thumbnail_id_not_post(){ - $result = $mpt->set_thumbnail(); + // if this is not a valid thumbnail_id it should not change the posts meta value for the instance key + $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); + $value_to_set_meta_before_set_thumbnail = 'foobar'; + $post = $this->factory->post->create_and_get(); + $post_type = $post->post_type; + $id = 'foobar'; + $_POST['post_id'] = $post->ID; + $_POST['thumbnail_id'] = 'abcdefg'; + + wp_set_current_user( $user_id ); + + // add a dummy value to test against after running MultiPostThumbnails::set_thumbnail + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $id, $value_to_set_meta_before_set_thumbnail ); + + $mpt = new MultiPostThumbnails(); + + $mpt->register( compact('post_type', 'id' ), false ); + $mpt->set_thumbnail(); + $actual = $mpt->get_thumbnail_id ( $post->ID ); + + // make sure that the value does not change by MultiPostThumbnails::set_thumbnail + $this->assertEquals( $actual, $value_to_set_meta_before_set_thumbnail ); + + $this->assertTrue( $this->exit_called ); - $document = new DOMDocument; - $document->preserveWhiteSpace = false; - $document->loadHTML( $result ); - $xpath = new DOMXPath ( $document ); - $anchor_tag = $xpath->query( "//a[@id='set-" . $post_type . "-" . $id . "-thumbnail']" ); - $this->assertEquals( 1, $anchor_tag->length ); } /** * @covers MultiPostThumbnails::set_thumbnail */ - public function test_set_thumbnail_is_a_post_thumbnail_html_returns_null() { + function test_set_thumbnail_id_is_not_image_attachment_attachment(){ - $post_type = 'post'; - $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); - $attachment_id = $this->factory->attachment->create_object( 'foo.jpg', $post_id, array( - 'post_mime_type' => 'image/jpeg', - 'post_type' => 'attachment' - ) ); + // if this is not a valid image it should not change the posts meta value for the instance key - $id = 'barfoo'; - $_POST['post_id'] = $post_id; - $_POST['thumbnail_id'] = $attachment_id; + $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); + $value_to_set_meta_before_set_thumbnail = 'foobar'; + $post = $this->factory->post->create_and_get(); + $post_type = $post->post_type; + $id = 'foobar'; + // set this as a 'post' post type (not an image) - $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) - ->disableOriginalConstructor() - ->setMethods( array( 'mpt_die', 'check_ajax_referer', 'get_meta_key', 'wp_get_attachment_image' ) ) - ->getMock(); + $_POST['post_id'] = $post->ID; - $mpt->register( array( 'label' => 'foobar', 'id' => $id ) ); + wp_set_current_user( $user_id ); + // add a dummy value to test against after running MultiPostThumbnails::set_thumbnail + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $id, $value_to_set_meta_before_set_thumbnail ); - $mpt->expects( $this->once() ) - ->method( 'check_ajax_referer' ); + $mpt = new MultiPostThumbnails(); + $mpt->register( compact('post_type', 'id' ), false ); + $mpt->set_thumbnail(); + $actual = $mpt->get_thumbnail_id ( $post->ID ); - $mpt->expects( $this->never() ) - ->method( 'get_meta_key' ); + // make sure that the value does not change by MultiPostThumbnails::set_thumbnail + $this->assertEquals( $actual, $value_to_set_meta_before_set_thumbnail ); - $mpt->expects( $this->once() ) - ->method( 'wp_get_attachment_image' ) - ->will( $this->returnValue( null ) ); + $this->assertTrue( $this->exit_called ); - $mpt->expects( $this->once() ) - ->method( 'mpt_die' ) - ->with( $this->equalTo( '0' ) ); + } - $mpt->set_thumbnail(); - } + /** + * @covers MultiPostThumbnails::get_thumbnail_id + */ + function test_get_thumbnail_id(){ + + $post = $this->factory->post->create_and_get(); + $post_type = $post->post_type; + $id = 'foobar'; + $value = 'fozbar'; + $mpt = new MultiPostThumbnails(); + $mpt->register( compact('post_type', 'id' ), false ); + + // add a dummy value to test against after running MultiPostThumbnails::set_thumbnail + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $id, $value ); + // validate that value is what is expected + $actual = MultiPostThumbnails::get_post_thumbnail_id( $post->post_type, $id, $post->ID ); + $this->assertEquals( $value, $actual ); + + } /** * @covers MultiPostThumbnails::set_meta */ - public function test_set_meta() { + function test_set_meta(){ - $post_type = 'page'; - $thumbnail_id = 'foo'; - $thumbnail_post_id = 'bar'; - $post_id = $this->factory->post->create( array( 'post_type' => $post_type ) ); - MultiPostThumbnails::set_meta( $post_id, $post_type, $thumbnail_id, $thumbnail_post_id); + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $post_type = $post->post_type; + $expected = $this->factory->attachment->create_object( 'foobar.jpg', $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); - $actual = get_post_meta( $post_id, "{$post_type}_{$thumbnail_id}_thumbnail_id", true ); + $id = 'foobar'; - $this->assertEquals( $thumbnail_post_id, $actual ); + // add a dummy value to test against after running MultiPostThumbnails::set_thumbnail + MultiPostThumbnails::set_meta($post_id, $post_type, $id, $expected); - } + $mpt = new MultiPostThumbnails(); + $mpt->register( compact('post_type', 'id' ), false ); + + //verify that we've set the meta as expected + + $actual = MultiPostThumbnails::get_post_thumbnail_id( $post->post_type, $id, $post->ID ); + $this->assertEquals( $expected, $actual ); + + } } From 4e32ba42b0415b9573361b0c7c7a1c0ab594ef70 Mon Sep 17 00:00:00 2001 From: Mat Gargano Date: Tue, 16 Sep 2014 14:35:57 -0400 Subject: [PATCH 29/29] add backupGlobal/restoreGlobal methods in favor of global backupGlobals --- tests/Voce_WP_UnitTestCase.php | 20 ++++++++++++++++++++ tests/test-multi-post-thumbnails.php | 1 - 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/Voce_WP_UnitTestCase.php b/tests/Voce_WP_UnitTestCase.php index 19e7c92..4f59633 100644 --- a/tests/Voce_WP_UnitTestCase.php +++ b/tests/Voce_WP_UnitTestCase.php @@ -8,6 +8,8 @@ function setUp() { parent::setUp(); + $this->backupGlobal( 'wp_scripts' ); + if ( function_exists( 'set_exit_overload' ) ) { set_exit_overload( array( $this, 'exit_overload' ) ); @@ -20,6 +22,8 @@ function tearDown() { parent::tearDown(); + $this->restoreGlobal( 'wp_script' ); + $this->exit_called = false; if ( function_exists( 'unset_exit_overload' ) ) { @@ -42,5 +46,21 @@ function exit_called() { } + function backupGlobal( $global ) { + if ( isset( $GLOBALS[$global] ) ) { + $this->backupGlobals[$global] = $GLOBALS[$global]; + } else { + $this->variablesUnset[$global] = true; + } + } + + function restoreGlobal( $global ) { + if ( isset( $this->backupGlobals[$global] ) ) { + $GLOBALS[$global] = $this->backupGlobals[$global]; + } elseif ( isset( $this->variablesUnset[ $global ] ) ) { + unset($GLOBALS[ $global ]); + } + } + } diff --git a/tests/test-multi-post-thumbnails.php b/tests/test-multi-post-thumbnails.php index ab97fe1..bfb848b 100644 --- a/tests/test-multi-post-thumbnails.php +++ b/tests/test-multi-post-thumbnails.php @@ -4,7 +4,6 @@ class TestMultiPostThumbnails extends Voce_WP_UnitTestCase { private $errors; - protected $backupGlobals = true; public function setUp() {