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..c68bb3d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +language: php + +php: + - 5.3 + - 5.4 + +env: + - WP_VERSION=latest WP_MULTISITE=0 + - WP_VERSION=latest 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 + +script: phpunit diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh new file mode 100755 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..12e1237 100644 --- a/multi-post-thumbnails.php +++ b/multi-post-thumbnails.php @@ -29,8 +29,21 @@ class MultiPostThumbnails { - public function __construct($args = array()) { - $this->register($args); + const THEME_SUPPORT = 'post-thumbnails'; + + public $label; + public $id; + protected $post_type; + protected $priority; + protected $context; + + /** + * @param array $args + * + * @codeCoverageIgnore + */ + public function __construct($args = array() ) { + $this->register( $args ); } /** @@ -47,59 +60,115 @@ 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. + * @param bool is this a shell call or do we need to register hooks * @return void */ - public function register($args = array()) { - global $wp_version; - + public function register( $args = array(), $shell = true ) { + $shell = !$shell ? true : false; + + // parse arugments and set defaults $defaults = array( - 'label' => null, - 'id' => null, + 'label' => ! $shell ? null : 'placeholder', + 'id' => null, 'post_type' => 'post', - 'priority' => 'low', - 'context' => 'side', + 'priority' => 'low', + 'context' => 'side', ); - $args = wp_parse_args($args, $defaults); - // Create and set properties - foreach($args as $k => $v) { + + $args = wp_parse_args( $args, $defaults ); + + $args = array_intersect_key( $args, $defaults ); + foreach ( $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__)); - } + // "label" and "id" are required + if ( is_null( $this->label ) || is_null( $this->id ) ) { + + $this->trigger_registration_error(); + return; + } - // add theme support if not already added - if (!current_theme_supports('post-thumbnails')) { - add_theme_support( 'post-thumbnails' ); + // Ensure that the current theme supports post-thumbnails since MPT relies on it + add_theme_support( self::THEME_SUPPORT ); + + if ( ! $shell ) { + + $this->attach_hooks(); + } + + } + + /** + * 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 ) { + + $error_message = $this->get_register_required_field_error_message(); + + trigger_error( $error_message ); + } - add_action('add_meta_boxes', array($this, 'add_metabox')); - if (version_compare($wp_version, '3.5', '<')) { + } + + /** + * Attach all necessary WP hooks to this instance + * + * @global string $wp_version + */ + public function attach_hooks() { + + global $wp_version; + + // 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 ); + } - + /** * 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"; @@ -121,9 +190,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_thumbnail_id( $post->ID ); + echo $this->post_thumbnail_html($thumbnail_id); + } /** @@ -134,6 +204,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']); @@ -145,13 +216,14 @@ public function add_attachment_field($form_fields, $post) { // check the post type to see if link needs to be added $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 = 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; @@ -160,32 +232,39 @@ 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; } /** * Enqueue admin JavaScripts * + * @param $hook + * * @return void */ 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; - if (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 + 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 ""; @@ -203,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; } @@ -229,6 +308,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(); @@ -258,32 +339,39 @@ 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) { - 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, $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', 'id' ), false ); + $mpt->get_post_thumbnail($post_id, $size, $attr, $link_to_original, true ); + unset( $mpt ); + } /** @@ -294,17 +382,39 @@ 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. - */ - 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); + * @return string + */ + 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', '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 = ''; } @@ -313,7 +423,13 @@ 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; + } /** @@ -325,7 +441,25 @@ 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; + + } + + /** + * 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 ); + } /** @@ -338,10 +472,14 @@ 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); + $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)) { @@ -352,7 +490,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; } @@ -361,13 +499,15 @@ 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) */ - 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', '<')) { // Use the old thickbox for versions prior to 3.5 $image_library_url = get_upload_iframe_src('image'); @@ -405,11 +545,11 @@ private 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 ); } @@ -417,6 +557,7 @@ private 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 @@ -424,9 +565,7 @@ public function set_thumbnail() { if ( !current_user_can('edit_post', $post_ID)) die('-1'); $thumbnail_id = intval($_POST['thumbnail_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()); die($this->post_thumbnail_html(null)); @@ -435,17 +574,16 @@ public function set_thumbnail() { if ($thumbnail_id && get_post($thumbnail_id)) { $thumbnail_html = wp_get_attachment_image($thumbnail_id, 'thumbnail'); if (!empty($thumbnail_html)) { - $this->set_meta($post_ID, $this->post_type, $this->id, $thumbnail_id); + self::set_meta($post_ID, $this->post_type, $this->id, $thumbnail_id); die($this->post_thumbnail_html($thumbnail_id)); } } - die('0'); } - + /** * set thumbnail meta - * + * * @param int $post_ID * @param string $post_type * @param string $thumbnail_id ID used to register the thumbnail @@ -456,8 +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); } + } if ( is_admin() ) load_plugin_textdomain( 'multiple-post-thumbnails', FALSE, basename( dirname( __FILE__ ) ) . '/languages/' ); } + + diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..87025b7 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,19 @@ + + + + ./tests/ + + + + + . + + + diff --git a/tests/Voce_WP_UnitTestCase.php b/tests/Voce_WP_UnitTestCase.php new file mode 100644 index 0000000..4f59633 --- /dev/null +++ b/tests/Voce_WP_UnitTestCase.php @@ -0,0 +1,66 @@ +backupGlobal( 'wp_scripts' ); + + if ( function_exists( 'set_exit_overload' ) ) { + + set_exit_overload( array( $this, 'exit_overload' ) ); + + } + + } + + function tearDown() { + + parent::tearDown(); + + $this->restoreGlobal( 'wp_script' ); + + $this->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; + + } + + 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/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..2b9eee9 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,25 @@ + array( 'multi-post-thumbnails/multi-post-thumbnails.php' ), +); + +require_once __DIR__ . '/pluggable.php'; + +require_once $_tests_dir . '/includes/functions.php'; + +function _manually_load_plugin() { + require dirname( __FILE__ ) . '/../multi-post-thumbnails.php'; +} +tests_add_filter( 'muplugins_loaded', '_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 ) { + + $this->errors[] = compact( + 'errno', + 'errstr', + 'errfile', + 'errline', + 'errcontext' + ); + + } + + public function assertError( $errstr, $errno = E_USER_NOTICE ) { + + 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() { + + /** + * Arguments for register() test: + * - 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( + /** + * All required args are specified + */ + array( + array( + 'id' => 'thumbnail-id', + 'label' => 'Thumbnail Label' + ), + array( + 'attach_hooks', + ), + true + ), + /** + * Missing required "id" arg + */ + array( + array( + 'label' => 'Thumbnail Label' + ), + array( + 'trigger_registration_error', + ), + false + ), + /** + * Missing required "label" arg + */ + array( + array( + 'id' => 'thumbnail-id' + ), + array( + 'trigger_registration_error', + ), + false + ) + ); + + } + + /** + * @dataProvider provider_test_register + * @covers MultiPostThumbnails::register + */ + 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() + ->setMethods( $expected_func_calls ) + ->getMock(); + + foreach ( $expected_func_calls as $expected_func ) { + + $mpt->expects( $this->once() ) + ->method( $expected_func ); + + } + + $mpt->register( $register_args ); + + $this->assertEquals( $theme_has_thumbnail_support, current_theme_supports( MultiPostThumbnails::THEME_SUPPORT ) ); + + } + + /** + * @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::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 + */ + 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' ) ); + + + $expected = 'post_bar_thumbnail_id'; + + // get the meta key + $actual = $mpt->get_meta_key(); + + $this->assertEquals( $expected, $actual ); + + } + + /** + * @covers MultiPostThumbnails::add_metabox + */ + 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'] ); + + } + + /** + * @covers MultiPostThumbnails::thumbnail_meta_box + */ + function test_thumbnail_meta_box() { + + $thumbnail_id = 'barfoo'; + $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' ) + ->disableOriginalConstructor() + ->setMethods( array( 'get_meta_key', 'post_thumbnail_html' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'get_meta_key' ) + ->will( $this->returnvalue( $meta_key ) ); + + $mpt->expects( $this->once() ) + ->method( 'post_thumbnail_html') + ->with ( $this->equalTo( $thumbnail_id ) ); + + $mpt->thumbnail_meta_box(); + + } + + /** + * Feed the post_id in to the $_GET superglobal + * + * @covers MultiPostThumbnails::add_attachment_field + */ + function test_add_attachment_field_post_set_in_get() { + + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $post_type = $post->post_type; + + $_GET['post_id'] = $post_id; + $id = 'foo'; + + $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 ); + + } + + /** + * Feed an array into $_POST to test async-upload + * + * @covers MultiPostThumbnails::add_attachment_field + */ + function test_add_attachment_field_post_superglobal_set() { + + $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 = 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_post_type_mismatch() { + + $id = 'foo'; + $post = $this->factory->post->create_and_get(); + $post_id = $post->ID; + $_GET['post_id'] = $post_id; + $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_no_post_parent() { + + $post = $this->factory->post->create_and_get(); + $post_type = $post->post_type; + $_POST = array(1,2,3); + $id = 'foo'; + + $mpt = new MultiPostThumbnails( array( + 'label' => 'Bar', + 'id' => $id, + 'post_type' => $post_type + ) ); + + $field = $mpt->add_attachment_field( array(), $post ); + $this->assertEquals( array(), $field ); + + } + + + /** + * 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 provider_test_enqueue_admin_scripts(){ + + 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( $version, $hook, $scripts_expected, $scripts_not_expected ) { + + $GLOBALS['wp_version'] = $version; + + $mpt = new MultiPostThumbnails(); + $mpt->enqueue_admin_scripts( $hook ); + foreach( $scripts_expected as $script ) { + + $this->assertTrue( wp_script_is( $script, 'enqueued' ) ); + + } + foreach( $scripts_not_expected as $script ) { + + $this->assertFalse( wp_script_is( $script, 'enqueued' ) ); + + } + + } + + /** + * @covers MultiPostThumbnails::admin_header_scripts + */ + function test_admin_header_scripts() { + + $post = $this->factory->post->create_and_get(); + $GLOBALS['post'] = $post; + $mpt = new MultiPostThumbnails; + ob_start(); + $mpt->admin_header_scripts(); + $output = ob_get_clean(); + $this->assertEquals( sprintf( '', $post->ID ) , $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; + + // 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 ) ); + + } + + /** + * @covers MultiPostThumbnails::filter_is_protected_meta + */ + function test_filter_is_protected_meta_meta_key_equals() { + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->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_meta_key_unequal() { + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->setMethods( array( 'get_meta_key' ) ) + ->getMock(); + + $mpt->expects( $this->once() ) + ->method( 'get_meta_key' ) + ->will( $this->returnValue( 'NOT_META_KEY' ) ); + + + // 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() { + + // 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( $expected, $actual ); + + } + + /** + * @covers MultiPostThumbnails::has_post_thumbnail + */ + 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'; + + // set the meta + MultiPostThumbnails::set_meta( $post->ID, $post->post_type, $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() { + + // if no post is set, it should return false + $actual = MultiPostThumbnails::has_post_thumbnail( 'post', 'foz', false ); + $this->assertFalse( $actual ); + + } + + /** + * @covers MultiPostThumbnails::the_post_thumbnail + */ + function test_the_post_thumbnail() { + + // test that MultiPostThumbnails::the_post_thumbnail echos the post thumbnail + + $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' + ) ); + + + $post_type = $post->post_type; + $id = 'foobar'; + + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + + $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() { + + + // 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']; + + $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' + ) ); + + + $post_type = $post->post_type; + $id = 'foobar'; + + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + + $mpt = $this->getMockBuilder( 'MultiPostThumbnails' ) + ->disableOriginalConstructor() + ->getMock(); + + $mpt->register(array('post_type' => 'post', 'id' => $id), false ); + + $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 + */ + function test_get_post_thumbnail(){ + + // test that MultiPostThumbnails::get_post_thumbnail returns the post thumbnail + + $filename = 'foo.jpg'; + $upload_directory_array = wp_upload_dir(); + $upload_directory = $upload_directory_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' + ) ); + $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 ); + + + } + + /** + * @covers MultiPostThumbnails::get_post_thumbnail + */ + function test_get_post_thumbnail_echo_link_to_original(){ + + // 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']; + + $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); + + 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 + */ + function test_get_post_thumbnail_no_post_thumbnail(){ + + // 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' ) ); + $id = 'foo'; + + $mpt = new MultiPostThumbnails( array( + 'label' => 'Foo', + 'id' => $id, + 'post_type' => 'post' + ) ); + + 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 + */ + + function test_get_post_thumbnail_id(){ + + // test that the proper URL is returned when calling MultiPostThumbnails::get_post_thumbnail_url + + $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' + ) ); + + + $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 + */ + function test_get_post_thumbnail_url(){ + + // 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; + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + + + $post_type = $post->post_type; + $id = 'foobar'; + + $expected = $upload_base_url . '/' . $filename; + + MultiPostThumbnails::set_meta( $post->ID, $post_type, $id, $attachment_id); + $actual = MultiPostThumbnails::get_post_thumbnail_url( $post_type, $id ); + + $this->assertEquals( $expected, $actual ); + + } + + + /** + * @covers MultiPostThumbnails::get_post_thumbnail_url + */ + function test_get_post_thumbnail_url_with_size(){ + + // 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; + $attachment_id = $this->factory->attachment->create_object( $filename, $post->ID, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + + + $post_type = $post->post_type; + $id = 'foobar'; + + $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' ); + + $this->assertEquals( $expected, $actual ); + + } + + + /** + * @covers MultiPostThumbnails::get_post_thumbnail_url + */ + function test_get_post_thumbnail_url_with_size_set_post_set_to_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' + ) ); + + $post_type = $post->post_type; + $id = 'foobar'; + $expected = ''; + + 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 ); + + } + + + /** + * @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; + + $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 ); + + $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 + */ + function test_set_thumbnail_user_can_thumbnail_id_negative_1(){ + + // test that the post meta gets deleted + + $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); + $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'; + + 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 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 + */ + function test_set_thumbnail_user_can(){ + + // 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' + ) ); + $post_type = $post->post_type; + $id = 'foobar'; + $_POST['post_id'] = $post->ID; + $_POST['thumbnail_id'] = $attachment_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 = 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 ); + + $this->assertTrue( $this->exit_called ); + + } + + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + function test_set_thumbnail_id_not_post(){ + + // 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 ); + + + } + + /** + * @covers MultiPostThumbnails::set_thumbnail + */ + function test_set_thumbnail_id_is_not_image_attachment_attachment(){ + + // if this is not a valid image 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'; + + // set this as a 'post' post type (not an image) + + $_POST['post_id'] = $post->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 = 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 ); + + + } + + + /** + * @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 + */ + function test_set_meta(){ + + $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' + ) ); + + $id = 'foobar'; + + // 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 ); + + } + +} + +